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 /*@function static bool ctuid_isAnyUserType (sef ctuid p_cid) @*/
37 # define ctuid_isAnyUserType(cid) \
38 ((cid) == CT_ABST || (cid) == CT_USER || (cid) == CT_NUMABST)
40 /*@private@*/ typedef struct {
43 ctype base; /* type I point to (or element of array) */
44 ctype ptr; /* type of pointer to me */
45 ctype array; /* type of array of me */
46 cstring unparse; /* unparse me, if memoized */
49 typedef /*@only@*/ ctentry o_ctentry;
54 /*@relnull@*/ /*@only@*/ o_ctentry *entries;
55 /* memoize matches...maybe in context? */
58 extern bool ctentry_isBogus (/*@sef@*/ ctentry p_c) /*@*/;
59 # define ctentry_isBogus(c) \
60 ((c)->kind == CTK_INVALID || (c)->kind == CTK_DNE)
62 static cttable cttab = { 0, 0, NULL };
64 static /*@notnull@*/ /*@only@*/ ctbase ctbase_createAbstract (typeId p_u);
65 static /*@notnull@*/ /*@only@*/ ctbase ctbase_createNumAbstract (typeId p_u);
66 static /*@observer@*/ cstring ctentry_doUnparse (ctentry p_c) /*@modifies p_c@*/;
67 static /*@only@*/ ctentry
68 ctentry_make (ctkind p_ctk, /*@keep@*/ ctbase p_c, ctype p_base,
69 ctype p_ptr, ctype p_array, /*@keep@*/ cstring p_unparse);
70 static /*@only@*/ ctentry ctentry_makeNew (ctkind p_ctk, /*@only@*/ ctbase p_c);
71 static /*@only@*/ cstring ctentry_unparse (ctentry p_c) /*@*/ ;
73 static void cttable_grow (void);
74 static ctype cttable_addDerived (ctkind p_ctk, /*@keep@*/ ctbase p_cnew, ctype p_base);
75 static ctype cttable_addFull (/*@keep@*/ ctentry p_cnew);
76 static bool ctentry_isInteresting (ctentry p_c) /*@*/;
77 static /*@notnull@*/ /*@only@*/ ctbase ctbase_makeFixedArray (ctype p_b, size_t p_size) /*@*/ ;
78 static bool ctbase_isAnytype (/*@notnull@*/ ctbase p_b) /*@*/ ;
81 ** These are file-static macros (used in ctype.c). No way to
82 ** declare them as static in C.
85 /*@-allmacros@*/ /*@-macrospec@*/ /*@-namechecks@*/
86 # define ctentry_getBase(c) ((c)->base)
87 # define ctentry_getKind(c) ((c)->kind)
88 # define ctentry_getArray(c) ((c)->array)
89 # define ctentry_getPtr(c) ((c)->ptr)
90 # define ctentry_isArray(c) ((c)->kind == CTK_ARRAY)
91 # define ctentry_isComplex(c) ((c)->kind == CTK_COMPLEX)
92 # define ctentry_isPlain(c) ((c)->kind == CTK_PLAIN)
93 # define ctentry_isPointer(c) ((c)->kind == CTK_PTR)
94 # define ctentry_setArray(c,b) ((c)->array = (b))
95 # define ctentry_setPtr(c,b) ((c)->ptr = (b))
97 # define ctbase_fixUser(c) (c = ctbase_realType(c))
98 /*@=allmacros@*/ /*@=macrospec@*/ /*@=namechecks@*/
100 static ctype cttable_addComplex (/*@notnull@*/ /*@only@*/ ctbase p_cnew);
101 static /*@observer@*/ ctbase ctype_getCtbase (ctype p_c) /*@*/ ;
102 static ctype ctype_makeConjAux (ctype p_c1, ctype p_c2, bool p_isExplicit) /*@*/ ;
103 static /*@notnull@*/ /*@observer@*/ ctbase ctype_getCtbaseSafe (ctype p_c) /*@*/ ;
104 static /*@observer@*/ ctentry ctype_getCtentry (ctype p_c) /*@*/ ;
105 static /*@observer@*/ /*@notnull@*/ ctbase
106 ctbase_realType (/*@notnull@*/ ctbase p_c) /*@*/ ;
107 static bool ctbase_isPointer (/*@notnull@*/ /*@dependent@*/ ctbase p_c) /*@*/ ;
108 static bool ctbase_isEitherArray (/*@notnull@*/ /*@dependent@*/ ctbase p_c) /*@*/ ;
109 static /*@observer@*/ enumNameList ctbase_elist (ctbase p_c) /*@*/ ;
110 static /*@only@*/ cstring ctbase_unparse (ctbase p_c) /*@*/ ;
111 static /*@only@*/ cstring ctbase_unparseDeep (ctbase p_c) /*@*/ ;
112 static /*@only@*/ /*@notnull@*/ ctbase ctbase_copy (/*@notnull@*/ ctbase p_c) /*@*/ ;
113 static void ctbase_free (/*@only@*/ ctbase p_c);
114 static /*@notnull@*/ /*@only@*/ ctbase ctbase_createPrim (cprim p_p) /*@*/ ;
115 static /*@notnull@*/ /*@only@*/ ctbase ctbase_createBool (void) /*@*/ ;
116 static /*@notnull@*/ /*@observer@*/ ctbase ctbase_getBool (void) /*@*/ ;
117 static /*@notnull@*/ /*@only@*/ ctbase ctbase_createUser (typeId p_u) /*@*/ ;
119 static /*@notnull@*/ /*@only@*/ ctbase
120 ctbase_createStruct (/*@only@*/ cstring p_n, /*@only@*/ uentryList p_f);
122 static /*@notnull@*/ /*@only@*/ ctbase
123 ctbase_createUnion (/*@keep@*/ cstring p_n, /*@only@*/ uentryList p_f);
124 static /*@notnull@*/ /*@only@*/ ctbase ctbase_createEnum (/*@keep@*/ cstring p_etag, /*@keep@*/ enumNameList p_emembers);
125 static /*@notnull@*/ /*@only@*/ ctbase ctbase_createUnknown (void);
126 static bool ctbase_match (ctbase p_c1, ctbase p_c2) /*@modifies nothing@*/;
127 static bool ctbase_matchDef (ctbase p_c1, ctbase p_c2) /*@modifies nothing@*/;
128 static bool ctbase_genMatch (ctbase p_c1, ctbase p_c2, bool p_force, bool p_arg, bool p_def, bool p_deep);
129 static bool ctbase_isAbstract (/*@notnull@*/ ctbase p_c) /*@*/ ;
130 static /*@notnull@*/ /*@only@*/ ctbase ctbase_makePointer (ctype p_b) /*@*/ ;
131 static /*@notnull@*/ /*@only@*/ ctbase ctbase_makeArray (ctype p_b) /*@*/ ;
132 static /*@notnull@*/ ctype
133 ctbase_makeFunction (ctype p_b, /*@only@*/ uentryList p_p) /*@*/ ;
134 static /*@notnull@*/ /*@observer@*/ ctbase
135 ctbase_realFunction (/*@notnull@*/ /*@dependent@*/ ctbase p_c) /*@*/ ;
136 static ctype ctbase_baseArrayPtr (/*@notnull@*/ ctbase p_c) /*@*/ ;
137 static ctype ctbase_baseFunction (/*@notnull@*/ ctbase p_c) /*@*/ ;
138 static /*@observer@*/ uentryList ctbase_argsFunction (/*@notnull@*/ ctbase p_c) /*@*/ ;
139 static /*@observer@*/ uentryList ctbase_getuentryList (/*@notnull@*/ ctbase p_c) /*@*/ ;
140 static ctype ctbase_newBase (ctype p_c, ctype p_p) /*@*/ ;
141 static ctype ctbase_newBaseExpFcn (ctype p_c, ctype p_p) /*@*/ ;
142 static bool ctbase_isFixedArray (/*@notnull@*/ ctbase p_c) /*@*/ ;
145 extern int cttable_lastIndex();
146 # define cttable_lastIndex() (cttab.size - 1)
152 /*@only@*/ uentryList params;
171 enumNameList members;
182 cprim prim; /* primitive */
183 typeId tid; /* abstract, user */
184 ctype base; /* ptr, array */
185 cfcn fcn; /* function */
186 tsu su; /* struct union */
187 tenum cenum; /* enum */
188 tconj conj; /* conj */
189 tfixed farray; /* fixed array */
198 static /*@falsenull@*/ bool ctbase_isUA (ctbase p_c) /*@*/ ;
199 static bool ctbase_isBaseUA(ctbase p_c) /*@*/ ;
200 static typeId ctbase_typeBaseUid(ctbase p_c) /*@*/ ;
201 static bool ctbase_isKind (/*@notnull@*/ ctbase p_c, ctuid p_kind) /*@*/ ;
202 static bool ctbase_isKind2 (/*@notnull@*/ ctbase p_c, ctuid p_kind1, ctuid p_kind2) /*@*/ ;
203 static /*@only@*/ /*@notnull@*/ ctbase
204 ctbase_getBaseType (/*@notnull@*/ ctbase p_c) /*@*/ ;
206 static /*@falsenull@*/ bool ctbase_isFunction(ctbase p_c) /*@*/ ;
208 /*@constant null ctbase ctbase_undefined; @*/
209 # define ctbase_undefined ((ctbase)0)
211 static /*@owned@*/ ctbase ctbase_bool = ctbase_undefined;
212 static /*@owned@*/ ctbase ctbase_unknown = ctbase_undefined;
214 static /*@falsenull@*/ bool ctbase_isDefined (ctbase c) /*@*/
216 return ((c) != ctbase_undefined);
219 static /*@truenull@*/ bool ctbase_isUndefined (ctbase c)
221 return ((c) == ctbase_undefined);
224 static ctkind ctype_getCtKind (ctype c)
226 ctentry ce = ctype_getCtentry (c);
228 return ctentry_getKind (ce);
231 static bool ctbase_isUser (ctbase c)
233 if (ctbase_isDefined (c))
235 return (ctbase_isKind (c, CT_USER));
243 static bool ctbase_isEnum (ctbase c)
245 if (ctbase_isDefined (c))
247 return (ctbase_isKind (c, CT_ENUM));
255 static bool ctbase_isExpFcn (ctbase c)
257 if (ctbase_isDefined (c))
259 return (c->type == CT_EXPFCN);
267 static /*@falsenull@*/ bool ctbase_isConj (ctbase c)
269 if (ctbase_isDefined (c))
271 return (c->type == CT_CONJ);
279 static bool ctuid_isAP (ctuid c) /*@*/
281 return (c == CT_ARRAY || c == CT_PTR);
284 static typeId ctbase_typeId (ctbase p_c);
285 static /*@only@*/ cstring ctbase_dump (ctbase p_c);
286 static /*@only@*/ ctbase ctbase_undump (char **p_c) /*@requires maxRead(*p_c) >= 2 @*/;
287 static int ctbase_compare (ctbase p_c1, ctbase p_c2, bool p_strict);
288 static bool ctbase_matchArg (ctbase p_c1, ctbase p_c2);
289 static /*@notnull@*/ /*@only@*/ ctbase
290 ctbase_makeConj (ctype p_c1, ctype p_c2, bool p_isExplicit) /*@*/ ;
291 static ctype ctbase_getConjA (/*@notnull@*/ ctbase p_c) /*@*/ ;
292 static ctype ctbase_getConjB (/*@notnull@*/ ctbase p_c) /*@*/ ;
293 static bool ctbase_isExplicitConj (/*@notnull@*/ ctbase p_c) /*@*/ ;
294 static bool ctbase_forceMatch (ctbase p_c1, ctbase p_c2) /*@modifies p_c1, p_c2@*/ ;
295 static /*@notnull@*/ /*@only@*/ ctbase ctbase_expectFunction (ctype p_c);
296 static bool ctbase_isVoidPointer(/*@notnull@*/ /*@dependent@*/ ctbase p_c) /*@*/ ;
297 static bool ctbase_isUnion (/*@notnull@*/ /*@temp@*/ ctbase p_c) /*@*/ ;
298 static bool ctbase_isStruct (/*@notnull@*/ /*@temp@*/ ctbase p_c) /*@*/ ;
299 static /*@observer@*/ cstring ctbase_enumTag (/*@notnull@*/ ctbase p_ct) /*@*/ ;
300 static /*@only@*/ cstring ctbase_unparseNotypes (ctbase p_c) /*@*/ ;
302 static /*@out@*/ /*@notnull@*/ /*@only@*/ ctbase ctbase_new (void) /*@*/ ;
303 static int nctbases = 0;
305 static /*@notnull@*/ /*@only@*/
306 ctbase ctbase_makeLiveFunction (ctype p_b, /*@only@*/ uentryList p_p);
308 static bool ctbase_isUnnamedSU (ctbase c)
310 return (ctbase_isDefined (c)
311 && (ctbase_isStruct (c) || ctbase_isUnion (c))
312 && isFakeTag (c->contents.su->name));
315 static /*@observer@*/ ctbase ctbase_realType (ctbase c)
319 typeId uid = ctbase_typeId (c);
321 if (usymtab_isBoolType (uid))
323 return ctbase_getBool ();
327 ctbase ret = ctype_getCtbase
328 (uentry_getRealType (usymtab_getTypeEntry (ctbase_typeId (c))));
330 llassert (ret != ctbase_undefined);
341 ctbase_isVoidPointer (/*@dependent@*/ /*@notnull@*/ ctbase c)
343 ctbase r = ctbase_realType (c);
345 return (ctbase_isKind (r, CT_PTR) &&
346 ctype_isVoid (r->contents.base));
350 ctbase_isPointer (/*@notnull@*/ /*@dependent@*/ ctbase c)
352 ctbase r = ctbase_realType (c);
354 return (ctbase_isKind (r, CT_PTR));
358 ctbase_isEitherArray (/*@notnull@*/ ctbase c)
360 ctbase r = ctbase_realType (c);
362 return (ctbase_isKind (r, CT_ARRAY)
363 || ctbase_isKind (r, CT_FIXEDARRAY));
367 ctbase_isFixedArray (/*@notnull@*/ ctbase c)
369 ctbase r = ctbase_realType (c);
371 return (ctbase_isKind (r, CT_FIXEDARRAY));
375 ctbase_isStruct (/*@notnull@*/ ctbase c)
377 ctbase r = ctbase_realType (c);
379 return (ctbase_isKind (r, CT_STRUCT));
383 ctbase_isUnion (/*@notnull@*/ ctbase c)
385 ctbase r = ctbase_realType (c);
387 return (ctbase_isKind (r, CT_UNION));
391 ** clean this up -> typeTable should store ctype
395 ctbase_typeBaseUid (ctbase c)
399 if (ctbase_isDefined (c))
405 return ctbase_typeBaseUid (ctype_getCtbase (c->contents.base));
407 else if (ct == CT_USER || ct == CT_ABST || ct == CT_NUMABST)
409 return c->contents.tid;
411 else if (ct == CT_FIXEDARRAY)
413 return ctbase_typeBaseUid (ctype_getCtbase (c->contents.farray->base));
417 llcontbuglit ("ctbase_typeBaseUid: bad call");
418 return typeId_invalid;
421 return typeId_invalid;
425 ctbase_isBaseUA (ctbase c)
429 if (ctbase_isDefined (c))
435 return ctbase_isBaseUA (ctype_getCtbase (c->contents.base));
437 else if (ct == CT_FIXEDARRAY)
439 return ctbase_isBaseUA (ctype_getCtbase (c->contents.farray->base));
442 return (ct == CT_USER || ct == CT_ABST || ct == CT_NUMABST);
448 ctbase_typeId (ctbase c)
452 return c->contents.tid;
456 if (ctbase_isConj (c))
458 return ctbase_typeId (ctype_getCtbase (ctbase_getConjA (c)));
462 llcontbug (message ("ctbase_typeId: bad call: %q", ctbase_unparse (c)));
463 return typeId_invalid;
468 static /*@only@*/ cstring
469 ctbase_unparse (ctbase c)
471 if (ctbase_isUndefined (c)) {
472 return cstring_makeLiteral ("<<undef>>");
478 return cstring_makeLiteral ("?");
480 return cstring_copy (context_printBoolName ());
482 return (cprim_unparse (c->contents.prim));
486 return (usymtab_getTypeEntryName (c->contents.tid));
488 return (message ("<expf: %t>", c->contents.base));
490 /* no spaces for multiple pointers */
492 if (ctype_isPointer (c->contents.base))
494 return (cstring_appendChar (cstring_copy (ctype_unparse (c->contents.base)), '*'));
498 return (message ("%t *", c->contents.base));
501 return (message ("%t [%d]",
502 c->contents.farray->base,
503 (int) c->contents.farray->size));
505 return (message ("%t []", c->contents.base));
507 return (message ("[function (%q) returns %t]",
508 uentryList_unparseParams (c->contents.fcn->params),
509 c->contents.fcn->rval));
511 if (cstring_isDefined (c->contents.su->name) &&
512 !cstring_isEmpty (c->contents.su->name) &&
513 !isFakeTag (c->contents.su->name))
515 return (message ("struct %s", c->contents.su->name));
519 return (message ("struct { %q }",
520 uentryList_unparseAbbrev (c->contents.su->fields)));
523 if (cstring_isDefined (c->contents.su->name) &&
524 !cstring_isEmpty (c->contents.su->name) &&
525 !isFakeTag (c->contents.su->name))
527 return (message ("union %s", c->contents.su->name));
531 return (message ("union { %q }",
532 uentryList_unparseAbbrev (c->contents.su->fields)));
535 if (isFakeTag (c->contents.cenum->tag))
537 return (message ("enum { %q }",
538 enumNameList_unparseBrief (c->contents.cenum->members)));
542 return (message ("enum %s { %q }",
543 c->contents.cenum->tag,
544 enumNameList_unparseBrief (c->contents.cenum->members)));
547 if (ctbase_isAnytype (c))
549 return (cstring_makeLiteral ("<any>"));
551 else if (c->contents.conj->isExplicit || context_getFlag (FLG_SHOWALLCONJS))
553 if (!ctype_isSimple (c->contents.conj->a) ||
554 !ctype_isSimple (c->contents.conj->b))
556 return (message ("<%t> | <%t>", c->contents.conj->a, c->contents.conj->b));
560 return (message ("%t | %t", c->contents.conj->a, c->contents.conj->b));
565 return (cstring_copy (ctype_unparse (c->contents.conj->a)));
572 static /*@only@*/ cstring
573 ctbase_unparseDeep (ctbase c)
575 if (ctbase_isUndefined (c))
577 return cstring_makeLiteral ("<<undef>>");
583 return cstring_makeLiteral ("?");
585 return cstring_copy (context_printBoolName ());
587 return (cprim_unparse (c->contents.prim));
589 if (cstring_isNonEmpty (c->contents.cenum->tag))
591 return (message ("enum %s { %q }",
592 c->contents.cenum->tag,
593 enumNameList_unparse (c->contents.cenum->members)));
597 return (message ("enum { %q }",
598 enumNameList_unparse (c->contents.cenum->members)));
603 return (usymtab_getTypeEntryName (c->contents.tid));
605 return (message ("<expf: %t>", c->contents.base));
607 return (message ("%t *", c->contents.base));
609 return (message ("%t [%d]", c->contents.farray->base,
610 (int) c->contents.farray->size));
612 return (message ("%t []", c->contents.base));
614 return (message ("[function (%q) returns %t]",
615 uentryList_unparse (c->contents.fcn->params),
616 c->contents.fcn->rval));
618 return (message ("struct %s { ... } ", c->contents.su->name));
620 return (message ("union %s { ... }", c->contents.su->name));
622 if (ctbase_isAnytype (c))
624 return (cstring_makeLiteral ("<any>"));
628 return (message ("%t", c->contents.conj->a));
635 static /*@only@*/ cstring
636 ctbase_unparseNotypes (ctbase c)
638 llassert (ctbase_isDefined (c));
643 return cstring_makeLiteral ("?");
645 return cstring_copy (context_printBoolName ());
647 return (cprim_unparse (c->contents.prim));
649 if (typeId_isInvalid (c->contents.tid))
651 return cstring_makeLiteral ("enum");
655 return (message ("T#%d", c->contents.tid));
658 return (message ("uT#%d", c->contents.tid));
660 return (message ("aT#%d", c->contents.tid));
662 return (message ("nT#%d", c->contents.tid));
664 return (message ("<expf: %q >", ctbase_unparseNotypes (ctype_getCtbase (c->contents.base))));
666 return (message ("%q *", ctbase_unparseNotypes (ctype_getCtbase (c->contents.base))));
668 return (message ("%q []", ctbase_unparseNotypes (ctype_getCtbase (c->contents.base))));
670 return (message ("[function (%d) returns %q]", uentryList_size (c->contents.fcn->params),
671 ctbase_unparseNotypes (ctype_getCtbase (c->contents.fcn->rval))));
673 return (message ("struct %s", c->contents.su->name));
675 return (message ("union %s", c->contents.su->name));
677 return (message ("[enumlist]"));
679 if (ctbase_isAnytype (c))
681 return (cstring_makeLiteral ("<any>"));
685 return (message ("%q/%q",
686 ctbase_unparseNotypes (ctype_getCtbase (c->contents.conj->a)),
687 ctbase_unparseNotypes (ctype_getCtbase (c->contents.conj->b))));
694 static /*@only@*/ cstring
695 ctbase_unparseDeclaration (ctbase c, /*@only@*/ cstring name) /*@*/
697 if (ctbase_isUndefined (c))
705 return (message ("? %q", name));
707 return (message ("%s %q", context_printBoolName (), name));
709 return (message ("%q %q", cprim_unparse (c->contents.prim), name));
713 return (message ("%q %q", usymtab_getTypeEntryName (c->contents.tid), name));
715 llcontbuglit ("ctbase_unparseDeclaration: expfcn");
718 if (ctype_isFunction (c->contents.base))
720 return ctbase_unparseDeclaration (ctype_getCtbase (c->contents.base), name);
724 cstring s = cstring_prependChar ('*', name);
725 cstring ret = ctbase_unparseDeclaration (ctype_getCtbase (c->contents.base), s);
730 return (message ("%q[%d]",
731 ctbase_unparseDeclaration (ctype_getCtbase (c->contents.farray->base), name),
732 (int) c->contents.farray->size));
734 return (message ("%q[]",
735 ctbase_unparseDeclaration (ctype_getCtbase (c->contents.base), name)));
738 cstring s = message ("%q(%q)", name,
739 uentryList_unparseParams (c->contents.fcn->params));
741 return (ctbase_unparseDeclaration
742 (ctype_getCtbase (c->contents.fcn->rval), s));
745 if (cstring_isDefined (c->contents.su->name) &&
746 !cstring_isEmpty (c->contents.su->name) &&
747 !isFakeTag (c->contents.su->name))
749 return (message ("struct %s %q", c->contents.su->name, name));
753 return (message ("struct { %q } %q",
754 uentryList_unparseAbbrev (c->contents.su->fields),
758 if (cstring_isDefined (c->contents.su->name) &&
759 !cstring_isEmpty (c->contents.su->name) &&
760 !isFakeTag (c->contents.su->name))
762 return (message ("union %s %q", c->contents.su->name, name));
766 return (message ("union { %q } %q",
767 uentryList_unparseAbbrev (c->contents.su->fields),
771 if (isFakeTag (c->contents.cenum->tag))
773 return (message ("enum { %q } %q",
774 enumNameList_unparseBrief (c->contents.cenum->members),
779 return (message ("enum %s { %q } %q",
780 c->contents.cenum->tag,
781 enumNameList_unparseBrief (c->contents.cenum->members),
785 if (ctbase_isAnytype (c))
787 return (message ("<any> %q", name));
789 else if (c->contents.conj->isExplicit || context_getFlag (FLG_SHOWALLCONJS))
791 if (!ctype_isSimple (c->contents.conj->a) ||
792 !ctype_isSimple (c->contents.conj->b))
794 cstring name1 = cstring_copy (name);
799 ctbase_unparseDeclaration
800 (ctype_getCtbase (c->contents.conj->a), name1),
801 ctbase_unparseDeclaration
802 (ctype_getCtbase (c->contents.conj->b), name)));
806 cstring s1 = ctbase_unparseDeclaration (ctype_getCtbase (c->contents.conj->a),
807 cstring_copy (name));
809 (message ("%q | %q", s1,
810 ctbase_unparseDeclaration (ctype_getCtbase (c->contents.conj->b),
817 return (cstring_copy (ctype_unparse (c->contents.conj->a)));
824 static ctbase ctbase_undump (d_char *c) /*@requires maxRead(*c) >= 2 @*/
834 return (ctbase_undefined);
836 return (ctbase_createUnknown ());
838 return (ctbase_createBool ());
840 res = ctbase_createPrim (cprim_fromInt (reader_getInt (c)));
841 reader_checkChar (c, '|');
844 res = ctbase_createUser (typeId_fromInt (reader_getInt (c)));
845 reader_checkChar (c, '|');
848 res = ctbase_createAbstract (typeId_fromInt (reader_getInt (c)));
849 reader_checkChar (c, '|');
852 res = ctbase_createNumAbstract (typeId_fromInt (reader_getInt (c)));
853 reader_checkChar (c, '|');
856 res = ctbase_makePointer (ctype_undump (c));
857 reader_checkChar (c, '|');
860 res = ctbase_makeArray (ctype_undump (c));
861 reader_checkChar (c, '|');
865 ctype ct = ctype_undump (c);
868 reader_checkChar (c, '/');
869 size = size_fromInt (reader_getInt (c));
870 reader_checkChar (c, '|');
871 return (ctbase_makeFixedArray (ct, size));
876 char *lp = strchr (*c, '(');
878 llassertfatal (lp != NULL);
881 ct = ctype_undump (c);
884 return (ctbase_makeLiveFunction (ct, uentryList_undump (c)));
891 char *lc = strchr (*c, '{');
893 llassert (lc != NULL);
896 sname = mstring_copy (*c);
904 i = (unsigned) atoi (sname + 1);
909 fields = uentryList_undumpFields (c, g_currentloc);
911 ctb = ctbase_createStruct (cstring_fromCharsO (sname), fields);
917 char *lc = strchr (*c, '{');
919 llassert (lc != NULL);
922 sname = mstring_copy (*c);
923 llassert (sname != NULL);
931 i = (unsigned) atoi (sname + 1);
935 return (ctbase_createUnion (cstring_fromCharsO (sname),
936 uentryList_undumpFields (c, g_currentloc)));
942 char *lc = strchr (*c, '{');
944 llassert (lc != NULL);
947 sname = mstring_copy (*c);
954 i = (unsigned) atoi (sname + 1);
958 ret = ctbase_createEnum (cstring_fromCharsO (sname),
959 enumNameList_undump (c));
967 isExplicit = bool_fromInt (reader_getInt (c));
968 reader_checkChar (c, '.');
969 c1 = ctype_undump (c);
970 reader_checkChar (c, '/');
971 c2 = ctype_undump (c);
972 reader_checkChar (c, '|');
974 return (ctbase_makeConj (c1, c2, isExplicit));
980 message ("Bad Library line (type): %s", cstring_fromChars (*c)));
982 /*drl bee: pbr*/ while (**c != '\0')
987 return ctbase_createUnknown ();
991 /* first letter of c encodes type: */
1007 static /*@only@*/ cstring
1008 ctbase_dump (ctbase c)
1010 if (!ctbase_isDefined (c))
1012 return cstring_makeLiteral ("?");
1018 return cstring_makeLiteral ("u");
1020 return cstring_makeLiteral ("b");
1022 return (message ("p%d|", c->contents.prim));
1024 return (message ("s%d|",
1025 usymtab_convertId (c->contents.tid)));
1027 return (message ("a%d|", usymtab_convertId (c->contents.tid)));
1029 return (message ("n%d|", usymtab_convertId (c->contents.tid)));
1031 return (message ("t%q|", ctype_dump (c->contents.base)));
1033 return (message ("y%q|", ctype_dump (c->contents.base)));
1035 return (message ("F%q/%d|",
1036 ctype_dump (c->contents.farray->base),
1037 (int) c->contents.farray->size));
1039 DPRINTF (("Dump function: %s", ctbase_unparse (c)));
1040 return (message ("f%q (%q)", ctype_dump (c->contents.fcn->rval),
1041 uentryList_dumpParams (c->contents.fcn->params)));
1043 return (message ("S%s{%q}", c->contents.su->name,
1044 uentryList_dumpFields (c->contents.su->fields)));
1046 return (message ("U%s{%q}", c->contents.su->name,
1047 uentryList_dumpFields (c->contents.su->fields)));
1052 if (cstring_isNonEmpty (c->contents.cenum->tag))
1054 s = message ("e%s{%q}",
1055 c->contents.cenum->tag,
1056 enumNameList_dump (c->contents.cenum->members));
1060 s = message ("e{%q}",
1061 enumNameList_dump (c->contents.cenum->members));
1066 return (message ("C%d.%q/%q|",
1067 bool_toInt (c->contents.conj->isExplicit),
1068 ctype_dump (c->contents.conj->a),
1069 ctype_dump (c->contents.conj->b)));
1071 /* should clean them up! */
1072 return (cstring_makeLiteral ("?"));
1074 llcontbug (message ("Cannot dump: %q", ctbase_unparse (c)));
1075 return (message ("u"));
1082 static /*@only@*/ ctbase
1083 ctbase_copy (/*@notnull@*/ ctbase c)
1088 return (ctbase_createUnknown ());
1090 return (ctbase_createBool ());
1092 return (ctbase_createEnum (cstring_copy (c->contents.cenum->tag),
1093 enumNameList_copy (c->contents.cenum->members)));
1095 return (ctbase_createPrim (c->contents.prim));
1097 return (ctbase_createUser (c->contents.tid));
1099 return (ctbase_createAbstract (c->contents.tid));
1101 return (ctbase_createNumAbstract (c->contents.tid));
1103 return (ctbase_expectFunction (c->contents.base));
1105 return (ctbase_makePointer (c->contents.base));
1107 return (ctbase_makeArray (c->contents.base));
1109 return (ctbase_makeLiveFunction (c->contents.fcn->rval,
1110 uentryList_copy (c->contents.fcn->params)));
1112 return (ctbase_createStruct (cstring_copy (c->contents.su->name),
1113 uentryList_copy (c->contents.su->fields)));
1115 return (ctbase_createUnion (cstring_copy (c->contents.su->name),
1116 uentryList_copy (c->contents.su->fields)));
1118 /*@i@*/ return (c); /* not a real copy for conj's */
1120 llbug (message ("ctbase_copy: %q", ctbase_unparse (c)));
1127 ctbase_elist (ctbase c)
1129 llassert (ctbase_isDefined (c));
1130 llassert (c->type == CT_ENUM);
1132 return (c->contents.cenum->members);
1136 ctbase_free (/*@only@*/ ctbase c)
1138 if (c == ctbase_bool || c == ctbase_unknown)
1140 /*@-mustfree@*/ return; /*@=mustfree@*/
1146 if (ctbase_isDefined (c))
1173 /*@i32@*/ /* uentryList_free (c->contents.fcn->params); */
1178 cstring_free (c->contents.su->name);
1179 uentryList_free (c->contents.su->fields);
1183 /* Don't bree conj's, */
1193 ** c should be * <unknown>
1196 static /*@only@*/ ctbase
1197 ctbase_expectFunction (ctype c)
1199 ctbase f = ctbase_new ();
1201 f->type = CT_EXPFCN;
1202 f->contents.base = c;
1208 ctbase_isExpectFunction (/*@notnull@*/ ctbase ct) /*@*/
1210 return (ct->type == CT_EXPFCN);
1214 ctbase_getExpectFunction (/*@notnull@*/ ctbase ct)
1216 llassert (ctbase_isExpectFunction (ct));
1217 return ct->contents.base;
1221 ctbase_genMatch (ctbase c1, ctbase c2, bool force, bool arg, bool def, bool deep)
1225 /* undefined types never match */
1227 if (ctbase_isUndefined (c1) || ctbase_isUndefined (c2))
1230 /* abstract types match user types of same name */
1232 c1 = ctbase_realType (c1);
1233 c2 = ctbase_realType (c2);
1235 DPRINTF (("Matching: %s / %s", ctbase_unparse (c1),
1236 ctbase_unparse (c2)));
1241 if (c1tid == CT_CONJ)
1243 return (ctbase_genMatch (ctype_getCtbase (c1->contents.conj->a), c2,
1244 force, arg, def, deep)
1245 || ctbase_genMatch (ctype_getCtbase (c1->contents.conj->b), c2,
1246 force, arg, def, deep));
1249 if (c2tid == CT_CONJ)
1251 return (ctbase_genMatch (c1, ctype_getCtbase (c2->contents.conj->a),
1252 force, arg, def, deep)
1253 || ctbase_genMatch (c1, ctype_getCtbase (c2->contents.conj->b),
1254 force, arg, def, deep));
1258 ** if the types don't match, there are some special cases...
1263 /* unknowns match anything */
1265 if (c1tid == CT_UNKNOWN || c2tid == CT_UNKNOWN)
1270 if (c1tid == CT_FIXEDARRAY
1271 && (c2tid == CT_ARRAY || (!def && c2tid == CT_PTR)))
1273 if (ctype_isVoid (c2->contents.base))
1275 return (context_getFlag (FLG_ABSTVOIDP) ||
1276 (!(ctype_isRealAbstract (c1->contents.farray->base)) &&
1277 !(ctype_isRealAbstract (c2->contents.base))));
1280 return (ctbase_genMatch (ctype_getCtbase (c1->contents.farray->base),
1281 ctype_getCtbase (c2->contents.base),
1282 force, arg, def, deep));
1286 if (c2tid == CT_FIXEDARRAY
1287 && (c1tid == CT_ARRAY || (!def && c1tid == CT_PTR)))
1289 if (ctype_isVoid (c1->contents.base))
1291 return (context_getFlag (FLG_ABSTVOIDP) ||
1292 (!(ctype_isRealAbstract (c2->contents.farray->base)) &&
1293 !(ctype_isRealAbstract (c1->contents.base))));
1296 return (ctbase_genMatch (ctype_getCtbase (c1->contents.base),
1297 ctype_getCtbase (c2->contents.farray->base),
1298 force, arg, def, deep));
1301 /* evs 2000-07-25: Bool's may match user/abstract types */
1303 if ((c1tid == CT_BOOL
1304 && (c2tid == CT_PRIM && cprim_isInt (c2->contents.prim))) ||
1306 && (c1tid == CT_PRIM && cprim_isInt (c1->contents.prim))))
1308 return (context_msgBoolInt ());
1311 if ((c1tid == CT_BOOL && (ctuid_isAnyUserType (c2tid)))) {
1312 ctype t2c = c2->contents.base;
1313 return (ctype_isBool (t2c));
1316 if ((c2tid == CT_BOOL && (ctuid_isAnyUserType (c1tid)))) {
1317 ctype t1c = c1->contents.base;
1319 return (ctype_isBool (t1c));
1322 if ((c1tid == CT_ENUM
1323 && (c2tid == CT_PRIM && cprim_isInt (c2->contents.prim))) ||
1325 && (c1tid == CT_PRIM && cprim_isInt (c1->contents.prim))))
1327 return (context_msgEnumInt ());
1331 ** arrays and pointers...yuk!
1333 ** Considered equivalent except in definitions.
1334 ** (e.g., function parameters are equivalent)
1340 if (ctuid_isAP (c1tid) && ctuid_isAP (c2tid))
1347 ** Function pointers can be removed.
1349 ** [function ..] is equivalent to [function ..] *
1352 if (c1tid == CT_PTR && c2tid == CT_FCN)
1354 if (ctype_isFunction (ctype_realType (c1->contents.base)))
1356 c1 = ctbase_realType (ctype_getCtbaseSafe (c1->contents.base));
1361 if (c2tid == CT_PTR && c1tid == CT_FCN)
1363 if (ctype_isFunction (ctype_realType (c2->contents.base)))
1365 c2 = ctbase_realType (ctype_getCtbaseSafe (c2->contents.base));
1371 ** we allow forward declarations to structures like,
1373 ** typedef struct _t *t;
1376 ** struct _t * to match t
1379 if (context_getFlag (FLG_FORWARDDECL))
1381 if (ctuid_isAnyUserType (c1tid))
1383 if (ctuid_isAP (c2tid))
1385 ctype ts = c2->contents.base;
1387 if (ctype_isUA (ts))
1389 typeId ttid = ctype_typeId (ts);
1390 typeId ctid = c1->contents.tid ;
1392 if (usymtab_matchForwardStruct (ctid, ttid))
1400 if (ctuid_isAnyUserType (c2tid))
1402 if (ctuid_isAP (c1tid))
1404 ctype ts = c1->contents.base;
1406 if (ctype_isUA (ts))
1408 typeId ttid = ctype_typeId (ts);
1409 typeId ctid = c2->contents.tid ;
1411 if (usymtab_matchForwardStruct (ctid, ttid))
1430 return (cprim_closeEnoughDeep (c1->contents.prim, c2->contents.prim));
1432 return (cprim_closeEnough (c1->contents.prim, c2->contents.prim));
1439 return (typeId_equal (c1->contents.tid, c2->contents.tid));
1441 return (cstring_equal (c1->contents.cenum->tag, c2->contents.cenum->tag));
1443 if (ctype_isVoid (c1->contents.base)
1444 || (ctype_isVoid (c2->contents.base)))
1446 if (ctype_isFunction (ctype_realType (c1->contents.base))
1447 || ctype_isFunction (ctype_realType (c2->contents.base)))
1449 return (!context_getFlag (FLG_CASTFCNPTR));
1453 return (context_getFlag (FLG_ABSTVOIDP) ||
1454 (!(ctype_isRealAbstract (c1->contents.base)) &&
1455 !(ctype_isRealAbstract (c2->contents.base))));
1460 /* Only allow one implicit function pointer. */
1462 if (!bool_equal (ctype_isRealPointer (c1->contents.base),
1463 ctype_isRealPointer (c2->contents.base))
1464 && (ctype_isRealFunction (c1->contents.base)
1465 || ctype_isRealFunction (c2->contents.base)))
1470 return (ctype_genMatch (c1->contents.base,
1471 c2->contents.base, force, arg, def, TRUE));
1474 if (ctype_isVoid (c1->contents.farray->base)
1475 || ctype_isVoid (c2->contents.farray->base))
1477 return (ctype_genMatch (c1->contents.farray->base,
1478 c2->contents.farray->base,
1479 force, arg, def, deep));
1481 if (ctype_isVoid (c1->contents.base) || ctype_isVoid (c2->contents.base))
1483 return (ctype_genMatch (c1->contents.base, c2->contents.base, force, arg, def, TRUE));
1485 return (ctype_genMatch (c1->contents.fcn->rval,
1486 c2->contents.fcn->rval,
1487 force, arg, def, TRUE)
1488 && uentryList_matchParams (c1->contents.fcn->params,
1489 c2->contents.fcn->params,
1493 DPRINTF (("Struct: %s / %s",
1494 c1->contents.su->name,
1495 c2->contents.su->name));
1497 if (isFakeTag (c1->contents.su->name)
1498 && isFakeTag (c2->contents.su->name))
1500 /* Both fake tags, check structure */
1501 if (cstring_equal (c1->contents.su->name, c2->contents.su->name))
1507 return uentryList_matchFields (c1->contents.su->fields,
1508 c2->contents.su->fields);
1513 if (!cstring_isEmpty (c1->contents.su->name))
1515 return (cstring_equal (c1->contents.su->name, c2->contents.su->name));
1519 if (!cstring_isEmpty (c2->contents.su->name))
1524 llcontbuglit ("ctbase_genMatch: match fields");
1529 llcontbug (message ("ctbase_genMatch: unknown type: %d\n", (int)c1tid));
1535 ** like ctbase_match, except for conjuncts:
1536 ** modifies conjuncts to match only
1540 ctbase_forceMatch (ctbase c1, ctbase c2) /*@modifies c1, c2@*/
1542 return (ctbase_genMatch (c1, c2, TRUE, FALSE, FALSE, FALSE));
1546 ctbase_match (ctbase c1, ctbase c2) /*@modifies nothing@*/
1548 return (ctbase_genMatch (c1, c2, FALSE, FALSE, FALSE, FALSE));
1552 ctbase_matchDef (ctbase c1, ctbase c2) /*@modifies nothing@*/
1554 return (ctbase_genMatch (c1, c2, FALSE, FALSE, TRUE, FALSE));
1558 ctbase_matchArg (ctbase c1, ctbase c2)
1560 return (ctbase_genMatch (c1, c2, FALSE, TRUE, FALSE, FALSE));
1563 static /*@out@*/ /*@only@*/ /*@notnull@*/ ctbase
1566 ctbase c = (ctbase) dmalloc (sizeof (*c));
1570 if (nctbases % 100 == 0 && nctbases > lastnc)
1572 llmsg (message ("ctbases: %d", nctbases));
1579 static /*@only@*/ ctbase
1580 ctbase_createPrim (cprim p)
1582 ctbase c = ctbase_new ();
1585 c->contents.prim = p;
1590 static /*@observer@*/ ctbase
1591 ctbase_getBool (void)
1593 /*@i@*/ return ctbase_createBool ();
1597 ctbase_createBool ()
1599 if (!ctbase_isDefined (ctbase_bool))
1601 ctbase_bool = ctbase_new ();
1602 ctbase_bool->type = CT_BOOL;
1603 ctbase_bool->contents.prim = CTX_BOOL;
1606 /*@-retalias@*/ /*@-globstate@*/
1608 /*@=retalias@*/ /*@=globstate@*/
1611 static /*@only@*/ ctbase
1612 ctbase_createUser (typeId u)
1614 ctbase c = ctbase_new ();
1617 c->contents.tid = u;
1619 llassert (typeId_isValid (u));
1624 static /*@only@*/ ctbase
1625 ctbase_createEnum (/*@keep@*/ cstring etag, /*@keep@*/ enumNameList emembers)
1627 ctbase c = ctbase_new ();
1631 if (cstring_isUndefined (etag))
1633 llcontbuglit ("Undefined enum tag!");
1637 c->contents.cenum = (tenum) dmalloc (sizeof (*c->contents.cenum));
1638 c->contents.cenum->tag = etag;
1639 c->contents.cenum->members = emembers;
1644 static /*@observer@*/ cstring
1645 ctbase_enumTag (/*@notnull@*/ ctbase ct)
1647 return (ct->contents.cenum->tag);
1650 static /*@only@*/ ctbase
1651 ctbase_createAbstract (typeId u)
1653 ctbase c = ctbase_new ();
1656 c->contents.tid = u;
1658 /* also check its abstract? */
1660 llassert (typeId_isValid (c->contents.tid));
1665 static /*@only@*/ ctbase
1666 ctbase_createNumAbstract (typeId u)
1668 ctbase c = ctbase_new ();
1670 c->type = CT_NUMABST;
1671 c->contents.tid = u;
1673 /* also check its abstract? */
1675 llassert (typeId_isValid (c->contents.tid));
1679 static /*@only@*/ ctbase
1680 ctbase_createUnknown (void)
1682 if (!ctbase_isDefined (ctbase_unknown))
1684 ctbase_unknown = ctbase_new ();
1685 ctbase_unknown->type = CT_UNKNOWN;
1686 ctbase_unknown->contents.prim = CTX_UNKNOWN;
1689 /*@-retalias@*/ /*@-globstate@*/
1690 return ctbase_unknown;
1691 /*@=retalias@*/ /*@=globstate@*/
1695 ** requires: result is not assigned to b
1696 ** (should copy, but no way to reclaim storage)
1699 static /*@only@*/ ctbase
1700 ctbase_makePointer (ctype b)
1702 ctbase c = ctbase_new ();
1705 c->contents.base = b;
1710 static /*@only@*/ ctbase
1711 ctbase_makeArray (ctype b)
1713 ctbase c = ctbase_new ();
1716 c->contents.base = b;
1721 static /*@notnull@*/ /*@only@*/ ctbase
1722 ctbase_makeFixedArray (ctype b, size_t size)
1724 ctbase c = ctbase_new ();
1726 c->type = CT_FIXEDARRAY;
1728 c->contents.farray = (tfixed) dmalloc (sizeof (*c->contents.farray));
1729 c->contents.farray->base = b;
1730 c->contents.farray->size = size;
1736 ctbase_makeFunction (ctype b, /*@only@*/ uentryList p)
1738 ctbase c = ctbase_new ();
1742 c->contents.fcn = (cfcn) dmalloc (sizeof (*c->contents.fcn));
1744 if (ctype_isFunction (b)) /* was: && ctype_isPointer (b)) */
1749 if (ctype_isPointer (b))
1751 ctb = ctype_getCtbase (ctype_baseArrayPtr (b));
1755 ctb = ctype_getCtbase (b);
1758 llassert (ctbase_isDefined (ctb));
1759 llassert (ctb->type == CT_FCN);
1761 rval = ctype_makeFunction (ctb->contents.fcn->rval, p);
1763 c->contents.fcn->rval = rval;
1764 c->contents.fcn->params = uentryList_copy (ctb->contents.fcn->params); /* no copy before */
1768 c->contents.fcn->rval = b;
1769 c->contents.fcn->params = uentryList_copy (p); /* no copy before */
1770 /*@-branchstate@*/ /* p is really released on this branch */
1774 ct = cttable_addComplex (c);
1775 return (ct); /* was: ctype_makePointer (ct)); */
1779 ctbase_makeNFFunction (ctype b, /*@only@*/ uentryList p)
1781 ctbase c = ctbase_new ();
1785 c->contents.fcn = (cfcn) dmalloc (sizeof (*c->contents.fcn));
1787 if (ctype_isFunction (b)) /* was && ctype_isPointer (b)) */
1792 if (ctype_isPointer (b))
1794 ctb = ctype_getCtbase (ctype_baseArrayPtr (b));
1798 ctb = ctype_getCtbase (b);
1801 llassert (ctbase_isDefined (ctb));
1802 llassert (ctb->type == CT_FCN);
1804 rval = ctype_makeNFParamsFunction (ctb->contents.fcn->rval, p);
1806 c->contents.fcn->rval = rval;
1807 c->contents.fcn->params = uentryList_copy (ctb->contents.fcn->params);
1811 c->contents.fcn->rval = b;
1812 c->contents.fcn->params = uentryList_copy (p);
1817 ct = cttable_addComplex (c);
1818 return (ct); /* was: ctype_makePointer (ct)); */
1821 static /*@only@*/ ctbase
1822 ctbase_makeLiveFunction (ctype b, /*@only@*/ uentryList p)
1824 ctbase c = ctbase_new ();
1828 c->contents.fcn = (cfcn) dmalloc (sizeof (*c->contents.fcn));
1829 c->contents.fcn->rval = b;
1830 c->contents.fcn->params = p;
1832 /*@-mustfree@*/ return (c); /*@=mustfree@*/
1835 static /*@observer@*/ /*@notnull@*/ ctbase
1836 ctbase_realFunction (/*@dependent@*/ /*@notnull@*/ ctbase c)
1840 if (c->type == CT_FCN)
1845 llassert (ctbase_isFunction (c));
1847 res = ctype_getCtbase (c->contents.base);
1849 llassert (ctbase_isDefined (res));
1855 ctbase_isFunction (ctbase c)
1857 llassert (c != ctbase_undefined);
1859 if (c->type == CT_FCN)
1865 if (c->type == CT_PTR)
1867 ctbase fcn = ctype_getCtbase (ctbase_baseArrayPtr (c));
1869 return (ctbase_isDefined (fcn) && fcn->type == CT_FCN);
1876 /* doesn't copy c1 and c2 */
1878 static /*@only@*/ ctbase
1879 ctbase_makeConj (ctype c1, ctype c2, bool isExplicit)
1881 ctbase c = ctbase_new ();
1885 c->contents.conj = (tconj) dmalloc (sizeof (*c->contents.conj));
1886 c->contents.conj->a = c1;
1887 c->contents.conj->b = c2;
1888 c->contents.conj->isExplicit = isExplicit;
1893 static bool ctbase_isAnytype (/*@notnull@*/ ctbase b)
1896 ** A unknown|dne conj is a special representation for an anytype.
1899 if (b->type == CT_CONJ)
1902 return (b->contents.conj->a == ctype_unknown
1903 && b->contents.conj->b == ctype_dne);
1904 /*@noaccess ctype@*/
1911 ctbase_getConjA (/*@notnull@*/ ctbase c)
1913 llassert (c->type == CT_CONJ);
1914 return (c->contents.conj->a);
1918 ctbase_getConjB (/*@notnull@*/ ctbase c)
1920 llassert (c->type == CT_CONJ);
1921 return (c->contents.conj->b);
1925 ctbase_isExplicitConj (/*@notnull@*/ ctbase c)
1927 llassert (c->type == CT_CONJ);
1928 return (c->contents.conj->isExplicit);
1931 static /*@only@*/ ctbase
1932 ctbase_createStruct (/*@only@*/ cstring n, /*@only@*/ uentryList f)
1934 ctbase c = ctbase_new ();
1936 c->type = CT_STRUCT;
1938 c->contents.su = (tsu) dmalloc (sizeof (*c->contents.su));
1939 c->contents.su->name = n;
1940 c->contents.su->fields = f;
1945 static /*@observer@*/ uentryList
1946 ctbase_getuentryList (/*@notnull@*/ ctbase c)
1948 c = ctbase_realType (c);
1950 if (!(c->type == CT_STRUCT || c->type == CT_UNION))
1951 llfatalbug (message ("ctbase_getuentryList: bad invocation: %q", ctbase_unparse (c)));
1953 return (c->contents.su->fields);
1957 ctbase_createUnion (/*@keep@*/ cstring n, /*@only@*/ uentryList f)
1959 ctbase c = ctbase_new ();
1963 c->contents.su = (tsu) dmalloc (sizeof (*c->contents.su));
1964 c->contents.su->name = n;
1965 c->contents.su->fields = f;
1971 ctbase_baseArrayPtr (/*@notnull@*/ ctbase c)
1974 c = ctbase_realType (c);
1977 if (ct == CT_FIXEDARRAY)
1979 return c->contents.farray->base;
1983 llassert (ctuid_isAP (ct));
1985 return c->contents.base;
1990 ctbase_baseFunction (/*@notnull@*/ ctbase c)
1993 c = ctbase_realFunction (c);
1995 if (c->type != CT_FCN)
1997 llfatalbug (message ("ctbase_baseFunction: bad call: %q", ctbase_unparse (c)));
2000 return (c->contents.fcn->rval);
2004 ctbase_argsFunction (/*@notnull@*/ ctbase c)
2007 c = ctbase_realFunction (c);
2009 if (c->type != CT_FCN)
2011 llfatalbug (message ("ctbase_argsFunction: bad call: %q",
2012 ctbase_unparse (c)));
2014 return (c->contents.fcn->params);
2018 ctbase_baseisExpFcn (ctype c)
2021 c = ctype_removePointers (c);
2023 cb = ctype_getCtbase (c);
2024 llassert (ctbase_isDefined (cb));
2026 if (cb->type == CT_FCN)
2028 c = ctype_removePointers (ctype_getReturnType (c));
2030 cb = ctype_getCtbase (c);
2031 llassert (ctbase_isDefined (cb));
2033 return (cb->type == CT_EXPFCN);
2039 ** ctbase_newBase behaves specially when p is a CONJ:
2041 ** c -> conj (newBase (c, p.a), p.b)
2045 ctbase_newBase (ctype c, ctype p)
2049 DPRINTF (("New base: %s / %s", ctype_unparse (c), ctype_unparse (p)));
2051 if (ctype_isUndefined (c) || ctype_isUnknown (c))
2056 cb = ctype_getCtbase (c);
2058 if (ctype_isConj (p))
2060 ctbase pb = ctype_getCtbase (p);
2062 llassert (ctbase_isDefined (pb));
2064 if (pb->contents.conj->isExplicit)
2066 return (ctype_makeExplicitConj (ctype_newBase (c, pb->contents.conj->a),
2067 pb->contents.conj->b));
2072 return (ctype_makeConj (ctype_newBase (c, pb->contents.conj->a),
2073 pb->contents.conj->b));
2078 if (ctbase_baseisExpFcn (c))
2080 return (ctbase_newBaseExpFcn (c, p));
2083 llassert (ctbase_isDefined (cb));
2103 cbn = ctbase_newBase (cb->contents.base, p);
2104 ret = ctype_makePointer (cbn);
2109 return (ctype_makeFixedArray (ctbase_newBase (cb->contents.farray->base, p),
2110 cb->contents.farray->size));
2112 return (ctype_makeArray (ctbase_newBase (cb->contents.base, p)));
2114 return (ctype_makeRawFunction (ctbase_newBase (cb->contents.fcn->rval, p),
2115 cb->contents.fcn->params));
2117 return (ctype_makeConjAux (ctbase_newBase (cb->contents.conj->a, p),
2118 ctbase_newBase (cb->contents.conj->b, p),
2119 cb->contents.conj->isExplicit));
2121 llcontbug (message ("ctbase_newBase: bad ctbase: %q", ctbase_unparse (cb)));
2128 ctbase_newBaseExpFcn (ctype c, ctype p)
2130 ctbase cb = ctype_getCtbase (c);
2133 ctype fp = ctype_unknown;
2134 uentryList ctargs = ctype_argsFunction (c);
2137 ** okay, this is really ugly...
2139 ** pointers inside <expf> mean pointers to the function;
2140 ** pointers outside <expf> are pointers to the return value;
2141 ** because its a function there is one superfluous pointer.
2145 ** bf is a ctype, used to derived structure of cb
2148 if (!ctbase_isFunction (cb))
2149 llbuglit ("ctbase_newBaseExpFcn: expFcn -> not a function");
2151 tmpct = ctype_getBaseType (ctype_getReturnType (c));
2154 ** pointers before expfcn -> p are pointers to function, not result
2158 tcb = ctype_getCtbase (tmpct);
2160 llassert (ctbase_isDefined (tcb));
2161 tmpct = tcb->contents.base;
2164 ** record pointers to base in fp
2167 while (!ctype_isUnknown (tmpct))
2169 if (ctype_isExpFcn (tmpct)) {
2170 ctbase ttcb = ctype_getCtbase (tmpct);
2173 ** evs 2000-05-16: This is necessary to deal with function pointers in parens.
2174 ** The whole function pointer parsing is a major kludge, but it seems to work,
2175 ** and I'm only embarrassed by it when I haven't look at the C spec recently...
2178 llassert (ctbase_isDefined (ttcb));
2179 tmpct = ttcb->contents.base;
2180 llassert (!ctype_isUnknown (tmpct));
2183 switch (ctype_getCtKind (tmpct))
2186 fp = ctype_makePointer (fp);
2187 /*@switchbreak@*/ break;
2189 fp = ctype_makeArray (fp);
2190 /*@switchbreak@*/ break;
2193 ctbase fbase = ctype_getCtbase (tmpct);
2195 if (ctbase_isFunction (fbase))
2197 fp = ctype_makeFunction (fp, uentryList_copy (ctargs));
2198 ctargs = ctbase_argsFunction (fbase);
2204 ("ctbase_newBaseExpFcn: fixing expfunction: bad complex type: %s [base: %q]",
2205 ctype_unparse (tmpct), ctbase_unparse (fbase)));
2212 (message ("ctbase_newBaseExpFcn: fixing expfunction: bad type: %s",
2213 ctype_unparse (tmpct)));
2217 tmpct = ctype_baseArrayPtr (tmpct);
2221 tmpct = ctype_getReturnType (c);
2224 ** pointers to expf are pointers to return value
2227 while (!ctype_isExpFcn (tmpct))
2229 switch (ctype_getCtKind (tmpct))
2232 p = ctype_makePointer (p);
2233 /*@switchbreak@*/ break;
2235 p = ctype_makeArray (p);
2236 /*@switchbreak@*/ break;
2239 ctbase fbase = ctype_getCtbase (tmpct);
2241 if (ctbase_isFunction (fbase))
2243 p = ctype_makeFunction (p, uentryList_copy (ctbase_argsFunction (fbase)));
2249 ("ctbase_newBaseExpFcn: fixing expfunction: bad complex type: %s",
2250 ctype_unparse (tmpct)));
2258 (message ("ctbase_newBaseExpFcn: fixing expfunction2: bad type: %t",
2263 tmpct = ctype_baseArrayPtr (tmpct);
2269 ** pointers to fp are pointers to function type
2272 ret = ctype_makeRawFunction (p, uentryList_copy (ctargs));
2274 while (ctype_getCtKind (fp) > CTK_PLAIN)
2276 switch (ctype_getCtKind (fp))
2279 ret = ctype_makePointer (ret);
2280 /*@switchbreak@*/ break;
2282 ret = ctype_makeArray (ret);
2283 /*@switchbreak@*/ break;
2286 ctbase fbase = ctype_getCtbase (fp);
2288 if (ctbase_isFunction (fbase))
2291 ctype_makeFunction (ret,
2292 uentryList_copy (ctbase_argsFunction (fbase)));
2303 llcontbug (message ("post-fixing expfunction: bad type: %t", fp));
2307 fp = ctype_baseArrayPtr (fp);
2315 ** returns lowest level base of c: plain type
2318 static /*@notnull@*/ /*@only@*/ ctbase
2319 ctbase_getBaseType (/*@notnull@*/ ctbase c)
2334 return (ctbase_copy (c));
2338 return (ctbase_getBaseType (ctype_getCtbaseSafe (c->contents.base)));
2341 return (ctbase_getBaseType (ctype_getCtbaseSafe (c->contents.farray->base)));
2342 case CT_CONJ: /* base type of A conj branch? */
2343 return (ctbase_getBaseType (ctype_getCtbaseSafe (c->contents.conj->a)));
2345 return (ctbase_copy (c));
2348 llfatalbug (message ("ctbase_getBaseType: bad ctbase: %q", ctbase_unparse (c)));
2355 ctbase_compare (ctbase c1, ctbase c2, bool strict)
2359 if (ctbase_isUndefined (c1) || ctbase_isUndefined (c2))
2361 llcontbuglit ("ctbase_compare: undefined ctbase");
2378 return (int_compare (c1->contents.prim, c2->contents.prim));
2382 return (int_compare (c1->contents.tid, c2->contents.tid));
2385 case CT_ENUM: /* for now, keep like abstract */
2388 return (int_compare (c1->contents.tid, c2->contents.tid));
2390 return (ctype_compare (c1->contents.base, c2->contents.base));
2392 INTCOMPARERETURN (c1->contents.farray->size, c2->contents.farray->size);
2394 return (ctype_compare (c1->contents.farray->base,
2395 c2->contents.farray->base));
2397 return (ctype_compare (c1->contents.base, c2->contents.base));
2400 COMPARERETURN (ctype_compare (c1->contents.fcn->rval, c2->contents.fcn->rval));
2404 return (uentryList_compareStrict (c1->contents.fcn->params,
2405 c2->contents.fcn->params));
2409 return (uentryList_compareParams (c1->contents.fcn->params,
2410 c2->contents.fcn->params));
2414 return (ctype_compare (c1->contents.base, c2->contents.base));
2417 /* evs 2000-07-28: this block was missing! */
2419 int ncmp = cstring_compare (c1->contents.su->name,
2420 c2->contents.su->name);
2423 if (isFakeTag (c1->contents.su->name)
2424 && isFakeTag (c2->contents.su->name)) {
2425 ; /* If they are both fake struct tags, don't require match. */
2432 DPRINTF (("Comparing fields: %s / %s",
2433 ctbase_unparse (c1),
2434 ctbase_unparse (c2)));
2436 return (uentryList_compareFields (c1->contents.su->fields,
2437 c2->contents.su->fields));
2440 COMPARERETURN (ctype_compare (c1->contents.conj->a,
2441 c2->contents.conj->a));
2442 COMPARERETURN (ctype_compare (c1->contents.conj->b,
2443 c2->contents.conj->b));
2444 return (bool_compare (c1->contents.conj->isExplicit,
2445 c2->contents.conj->isExplicit));
2452 ctbase_compareStrict (/*@notnull@*/ ctbase c1, /*@notnull@*/ ctbase c2)
2454 return (ctbase_compare (c1, c2, TRUE));
2457 static bool ctbase_equivStrict (/*@notnull@*/ ctbase c1, /*@notnull@*/ ctbase c2)
2459 return (ctbase_compareStrict (c1,c2) == 0);
2462 static bool ctbase_equiv (/*@notnull@*/ ctbase c1, /*@notnull@*/ ctbase c2)
2464 return (ctbase_compare (c1, c2, FALSE) == 0);
2468 ctbase_isKind (/*@notnull@*/ ctbase c, ctuid kind)
2476 return (ctbase_isKind (ctype_getCtbaseSafe (c->contents.conj->a), kind) ||
2477 ctbase_isKind (ctype_getCtbaseSafe (c->contents.conj->b), kind));
2483 ctbase_isKind2 (/*@notnull@*/ ctbase c, ctuid kind1, ctuid kind2)
2487 if (ck == kind1 || ck == kind2)
2491 return (ctbase_isKind2 (ctype_getCtbaseSafe (c->contents.conj->a), kind1, kind2) ||
2492 ctbase_isKind2 (ctype_getCtbaseSafe (c->contents.conj->b), kind1, kind2));
2498 ctbase_isAbstract (/*@notnull@*/ ctbase c)
2500 return (c->type == CT_ABST || c->type == CT_NUMABST);
2504 ctbase_isNumAbstract (/*@notnull@*/ ctbase c)
2506 return (c->type == CT_NUMABST);
2509 static bool ctbase_isUA (ctbase c)
2511 return (ctbase_isDefined (c) && (ctuid_isAnyUserType (c->type)));
2515 ctbase_almostEqual (ctbase c1, ctbase c2)
2519 /* undefined types never match */
2521 if (ctbase_isUndefined (c1) || ctbase_isUndefined (c2))
2527 if (c1tid == CT_FIXEDARRAY && c2tid == CT_ARRAY)
2529 return (ctbase_almostEqual (ctype_getCtbase (c1->contents.farray->base),
2530 ctype_getCtbase (c2->contents.base)));
2533 if (c2tid == CT_FIXEDARRAY && c1tid == CT_ARRAY)
2535 return (ctbase_almostEqual (ctype_getCtbase (c1->contents.base),
2536 ctype_getCtbase (c2->contents.farray->base)));
2547 return (cprim_equal (c1->contents.prim, c2->contents.prim));
2553 return (typeId_equal (c1->contents.tid, c2->contents.tid));
2555 return (cstring_equal (c1->contents.cenum->tag, c2->contents.cenum->tag));
2557 return (ctype_almostEqual (c1->contents.base, c2->contents.base));
2559 return (ctype_almostEqual (c1->contents.farray->base,
2560 c2->contents.farray->base));
2562 return (ctype_almostEqual (c1->contents.base, c2->contents.base));
2564 return (ctype_almostEqual (c1->contents.fcn->rval, c2->contents.fcn->rval)
2565 && uentryList_matchParams (c1->contents.fcn->params,
2566 c2->contents.fcn->params, FALSE, TRUE));
2569 if (!cstring_isEmpty (c1->contents.su->name))
2571 return (cstring_equal (c1->contents.su->name, c2->contents.su->name));
2575 if (!cstring_isEmpty (c2->contents.su->name))
2580 llcontbuglit ("ctbase_almostEqual: match fields");
2584 llcontbug (message ("ctbase_almostEqual: unknown type: %d\n", (int)c1tid));
2589 /*drl added July 02, 001
2590 called by ctype_getArraySize
2593 size_t ctbase_getArraySize (ctbase ctb)
2595 /*drl 1/25/2002 fixed discovered by Jim Francis */
2598 llassert (ctbase_isDefined (ctb) );
2599 r = ctbase_realType (ctb);
2600 llassert (ctbase_isFixedArray(r) );
2602 return (r->contents.farray->size);
2605 bool ctbase_isBigger (ctbase ct1, ctbase ct2)
2607 if (ct1 != NULL && ct2 != NULL
2608 && (ct1->type == CT_PRIM && ct2->type == CT_PRIM))
2610 /* Only compare sizes for primitives */
2611 cprim cp1 = ct1->contents.prim;
2612 cprim cp2 = ct2->contents.prim;
2613 int nbits1 = cprim_getExpectedBits (cp1);
2614 int nbits2 = cprim_getExpectedBits (cp2);
2616 if (nbits1 > nbits2) {