Various minor fixes for compiler/linter (other then splint itself) warnings.
[splint-patched.git] / src / ctbase.i
blob45bb5946888fda02c295a6f3a933ea9d2ab8b1df
1 /* ;-*-C-*-;
2 ** Splint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2003 University of Virginia,
4 ** Massachusetts Institute of Technology
5 **
6 ** This program is free software; you can redistribute it and/or modify it
7 ** under the terms of the GNU General Public License as published by the
8 ** Free Software Foundation; either version 2 of the License, or (at your
9 ** option) any later version.
10 **
11 ** This program is distributed in the hope that it will be useful, but
12 ** WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 ** General Public License for more details.
15 **
16 ** The GNU General Public License is available from http://www.gnu.org/ or
17 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18 ** MA 02111-1307, USA.
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
25 ** ctbase.i
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.)
32 /*@access cprim*/
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 {
44 ctkind kind;
45 ctbase ctbase;
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 */
50 } *ctentry ;
52 typedef /*@only@*/ ctentry o_ctentry;
54 typedef struct {
55 int size;
56 int nspace;
57 /*@relnull@*/ /*@only@*/ o_ctentry *entries;
58 /* memoize matches...maybe in context? */
59 } cttable ;
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) /*@*/ ;
83 /*
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 void ctbase_free (/*@only@*/ ctbase p_c);
116 static /*@notnull@*/ /*@only@*/ ctbase ctbase_createPrim (cprim p_p) /*@*/ ;
117 static /*@notnull@*/ /*@only@*/ ctbase ctbase_createBool (void) /*@*/ ;
118 static /*@notnull@*/ /*@observer@*/ ctbase ctbase_getBool (void) /*@*/ ;
119 static /*@notnull@*/ /*@only@*/ ctbase ctbase_createUser (typeId p_u) /*@*/ ;
121 static /*@notnull@*/ /*@only@*/ ctbase
122 ctbase_createStruct (/*@only@*/ cstring p_n, /*@only@*/ uentryList p_f);
124 static /*@notnull@*/ /*@only@*/ ctbase
125 ctbase_createUnion (/*@keep@*/ cstring p_n, /*@only@*/ uentryList p_f);
126 static /*@notnull@*/ /*@only@*/ ctbase ctbase_createEnum (/*@keep@*/ cstring p_etag, /*@keep@*/ enumNameList p_emembers);
127 static /*@notnull@*/ /*@only@*/ ctbase ctbase_createUnknown (void);
128 static bool ctbase_match (ctbase p_c1, ctbase p_c2) /*@modifies nothing@*/;
129 static bool ctbase_matchDef (ctbase p_c1, ctbase p_c2) /*@modifies nothing@*/;
130 static bool ctbase_genMatch (ctbase p_c1, ctbase p_c2, bool p_force, bool p_arg, bool p_def, bool p_deep);
131 static bool ctbase_isAbstract (/*@notnull@*/ ctbase p_c) /*@*/ ;
132 static /*@notnull@*/ /*@only@*/ ctbase ctbase_makePointer (ctype p_b) /*@*/ ;
133 static /*@notnull@*/ /*@only@*/ ctbase ctbase_makeArray (ctype p_b) /*@*/ ;
134 static /*@notnull@*/ ctype
135 ctbase_makeFunction (ctype p_b, /*@only@*/ uentryList p_p) /*@*/ ;
136 static /*@notnull@*/ /*@observer@*/ ctbase
137 ctbase_realFunction (/*@notnull@*/ /*@dependent@*/ ctbase p_c) /*@*/ ;
138 static ctype ctbase_baseArrayPtr (/*@notnull@*/ ctbase p_c) /*@*/ ;
139 static ctype ctbase_baseFunction (/*@notnull@*/ ctbase p_c) /*@*/ ;
140 static /*@observer@*/ uentryList ctbase_argsFunction (/*@notnull@*/ ctbase p_c) /*@*/ ;
141 static /*@observer@*/ uentryList ctbase_getuentryList (/*@notnull@*/ ctbase p_c) /*@*/ ;
142 static ctype ctbase_newBase (ctype p_c, ctype p_p) /*@*/ ;
143 static ctype ctbase_newBaseExpFcn (ctype p_c, ctype p_p) /*@*/ ;
144 static bool ctbase_isFixedArray (/*@notnull@*/ ctbase p_c) /*@*/ ;
146 /*@-macroundef@*/
147 extern int cttable_lastIndex(void);
148 # define cttable_lastIndex() (cttab.size - 1)
149 /*@=macroundef@*/
151 typedef struct
153 ctype rval;
154 /*@only@*/ uentryList params;
155 } *cfcn;
157 typedef struct
159 cstring name;
160 uentryList fields;
161 } *tsu;
163 typedef struct
165 ctype a;
166 ctype b;
167 bool isExplicit;
168 } *tconj;
170 typedef struct
172 cstring tag;
173 enumNameList members;
174 } *tenum;
176 typedef struct
178 ctype base;
179 size_t size;
180 } *tfixed;
182 typedef union
184 cprim prim; /* primitive */
185 typeId tid; /* abstract, user */
186 ctype base; /* ptr, array */
187 cfcn fcn; /* function */
188 tsu su; /* struct union */
189 tenum cenum; /* enum */
190 tconj conj; /* conj */
191 tfixed farray; /* fixed array */
192 } uconts;
194 struct s_ctbase
196 ctuid type;
197 uconts contents;
200 static /*@falsenull@*/ bool ctbase_isUA (ctbase p_c) /*@*/ ;
201 static bool ctbase_isKind (/*@notnull@*/ ctbase p_c, ctuid p_kind) /*@*/ ;
202 static /*@falsenull@*/ bool ctbase_isFunction(ctbase p_c) /*@*/ ;
204 /*@constant null ctbase ctbase_undefined; @*/
205 # define ctbase_undefined ((ctbase)0)
207 static /*@owned@*/ ctbase ctbase_bool = ctbase_undefined;
208 static /*@owned@*/ ctbase ctbase_unknown = ctbase_undefined;
210 static /*@falsenull@*/ bool ctbase_isDefined (ctbase c) /*@*/
212 return ((c) != ctbase_undefined);
215 static /*@truenull@*/ bool ctbase_isUndefined (ctbase c)
217 return ((c) == ctbase_undefined);
220 static ctkind ctype_getCtKind (ctype c)
222 ctentry ce = ctype_getCtentry (c);
224 return ctentry_getKind (ce);
227 static bool ctbase_isUser (ctbase c)
229 if (ctbase_isDefined (c))
231 return (ctbase_isKind (c, CT_USER));
233 else
235 return FALSE;
239 static bool ctbase_isEnum (ctbase c)
241 if (ctbase_isDefined (c))
243 return (ctbase_isKind (c, CT_ENUM));
245 else
247 return FALSE;
251 static bool ctbase_isExpFcn (ctbase c)
253 if (ctbase_isDefined (c))
255 return (c->type == CT_EXPFCN);
257 else
259 return FALSE;
263 static /*@falsenull@*/ bool ctbase_isConj (ctbase c)
265 if (ctbase_isDefined (c))
267 return (c->type == CT_CONJ);
269 else
271 return FALSE;
275 static bool ctuid_isAP (ctuid c) /*@*/
277 return (c == CT_ARRAY || c == CT_PTR);
280 static typeId ctbase_typeId (ctbase p_c);
281 static /*@only@*/ cstring ctbase_dump (ctbase p_c);
282 static /*@only@*/ ctbase ctbase_undump (char **p_c) /*@requires maxRead(*p_c) >= 2 @*/;
283 static int ctbase_compare (ctbase p_c1, ctbase p_c2, bool p_strict);
284 static bool ctbase_matchArg (ctbase p_c1, ctbase p_c2);
285 static /*@notnull@*/ /*@only@*/ ctbase
286 ctbase_makeConj (ctype p_c1, ctype p_c2, bool p_isExplicit) /*@*/ ;
287 static ctype ctbase_getConjA (/*@notnull@*/ ctbase p_c) /*@*/ ;
288 static ctype ctbase_getConjB (/*@notnull@*/ ctbase p_c) /*@*/ ;
289 static bool ctbase_isExplicitConj (/*@notnull@*/ ctbase p_c) /*@*/ ;
290 static bool ctbase_forceMatch (ctbase p_c1, ctbase p_c2) /*@modifies p_c1, p_c2@*/ ;
291 static /*@notnull@*/ /*@only@*/ ctbase ctbase_expectFunction (ctype p_c);
292 static bool ctbase_isVoidPointer(/*@notnull@*/ /*@dependent@*/ ctbase p_c) /*@*/ ;
293 static bool ctbase_isUnion (/*@notnull@*/ /*@temp@*/ ctbase p_c) /*@*/ ;
294 static bool ctbase_isStruct (/*@notnull@*/ /*@temp@*/ ctbase p_c) /*@*/ ;
295 static /*@observer@*/ cstring ctbase_enumTag (/*@notnull@*/ ctbase p_ct) /*@*/ ;
297 static /*@out@*/ /*@notnull@*/ /*@only@*/ ctbase ctbase_new (void) /*@*/ ;
298 static int nctbases = 0;
300 static /*@notnull@*/ /*@only@*/
301 ctbase ctbase_makeLiveFunction (ctype p_b, /*@only@*/ uentryList p_p);
303 # ifdef DEADCODE
304 static bool ctbase_isUnnamedSU (ctbase c)
306 return (ctbase_isDefined (c)
307 && (ctbase_isStruct (c) || ctbase_isUnion (c))
308 && isFakeTag (c->contents.su->name));
310 # endif /* DEADCODE */
312 static /*@observer@*/ ctbase ctbase_realType (ctbase c)
314 if (ctbase_isUA (c))
316 typeId uid = ctbase_typeId (c);
318 if (usymtab_isBoolType (uid))
320 return ctbase_getBool ();
322 else
324 ctbase ret = ctype_getCtbase
325 (uentry_getRealType (usymtab_getTypeEntry (ctbase_typeId (c))));
327 llassert (ret != ctbase_undefined);
328 return ret;
331 else
333 return c;
337 static bool
338 ctbase_isVoidPointer (/*@dependent@*/ /*@notnull@*/ ctbase c)
340 ctbase r = ctbase_realType (c);
342 return (ctbase_isKind (r, CT_PTR) &&
343 ctype_isVoid (r->contents.base));
346 static bool
347 ctbase_isPointer (/*@notnull@*/ /*@dependent@*/ ctbase c)
349 ctbase r = ctbase_realType (c);
351 return (ctbase_isKind (r, CT_PTR));
354 static bool
355 ctbase_isEitherArray (/*@notnull@*/ ctbase c)
357 ctbase r = ctbase_realType (c);
359 return (ctbase_isKind (r, CT_ARRAY)
360 || ctbase_isKind (r, CT_FIXEDARRAY));
363 static bool
364 ctbase_isFixedArray (/*@notnull@*/ ctbase c)
366 ctbase r = ctbase_realType (c);
368 return (ctbase_isKind (r, CT_FIXEDARRAY));
371 static bool
372 ctbase_isStruct (/*@notnull@*/ ctbase c)
374 ctbase r = ctbase_realType (c);
376 return (ctbase_isKind (r, CT_STRUCT));
379 static bool
380 ctbase_isUnion (/*@notnull@*/ ctbase c)
382 ctbase r = ctbase_realType (c);
384 return (ctbase_isKind (r, CT_UNION));
388 ** clean this up -> typeTable should store ctype
391 #ifdef DEADCODE
392 static typeId
393 ctbase_typeBaseUid (ctbase c)
395 ctuid ct;
397 if (ctbase_isDefined (c))
399 ct = c->type;
401 if (ctuid_isAP (ct))
403 return ctbase_typeBaseUid (ctype_getCtbase (c->contents.base));
405 else if (ct == CT_USER || ct == CT_ABST || ct == CT_NUMABST)
407 return c->contents.tid;
409 else if (ct == CT_FIXEDARRAY)
411 return ctbase_typeBaseUid (ctype_getCtbase (c->contents.farray->base));
413 else
415 llcontbuglit ("ctbase_typeBaseUid: bad call");
416 return typeId_invalid;
419 return typeId_invalid;
422 static bool
423 ctbase_isBaseUA (ctbase c)
425 ctuid ct;
427 if (ctbase_isDefined (c))
429 ct = c->type;
431 if (ctuid_isAP (ct))
433 return ctbase_isBaseUA (ctype_getCtbase (c->contents.base));
435 else if (ct == CT_FIXEDARRAY)
437 return ctbase_isBaseUA (ctype_getCtbase (c->contents.farray->base));
439 else
440 return (ct == CT_USER || ct == CT_ABST || ct == CT_NUMABST);
442 return FALSE;
444 #endif
446 static typeId
447 ctbase_typeId (ctbase c)
449 if (ctbase_isUA (c))
451 return c->contents.tid;
453 else
455 if (ctbase_isConj (c))
457 if (ctype_isUA (ctbase_getConjA (c))) {
458 return ctbase_typeId (ctype_getCtbase (ctbase_getConjA (c)));
459 } else if (ctype_isUA (ctbase_getConjB (c))) {
460 return ctbase_typeId (ctype_getCtbase (ctbase_getConjB (c)));
461 } else {
462 llcontbug (message ("ctbase_typeId: bad call: %q", ctbase_unparse (c)));
463 return typeId_invalid;
466 else
468 llcontbug (message ("ctbase_typeId: bad call: %q", ctbase_unparse (c)));
469 return typeId_invalid;
474 static /*@only@*/ cstring
475 ctbase_unparse (ctbase c)
477 if (ctbase_isUndefined (c)) {
478 return cstring_makeLiteral ("<<undef>>");
481 switch (c->type)
483 case CT_UNKNOWN:
484 return cstring_makeLiteral ("?");
485 case CT_BOOL:
486 return cstring_copy (context_printBoolName ());
487 case CT_PRIM:
488 return (cprim_unparse (c->contents.prim));
489 case CT_USER:
490 case CT_ABST:
491 case CT_NUMABST:
492 return (usymtab_getTypeEntryName (c->contents.tid));
493 case CT_EXPFCN:
494 return (message ("<expf: %t>", c->contents.base));
495 case CT_PTR:
496 /* no spaces for multiple pointers */
498 if (ctype_isPointer (c->contents.base))
500 return (cstring_appendChar (cstring_copy (ctype_unparse (c->contents.base)), '*'));
502 else
504 return (message ("%t *", c->contents.base));
506 case CT_FIXEDARRAY:
508 ** C prints out array declarations backwards, if
509 ** base is an array need to print out in reverse order.
512 if (ctype_isArray (c->contents.farray->base))
514 ctype base = c->contents.farray->base;
515 cstring res = message ("[%d]", (int) c->contents.farray->size);
517 while (ctype_isArray (base))
519 if (ctype_isFixedArray (base))
521 res = message ("%q[%d]",
522 res, (int) ctype_getArraySize (base));
524 else
526 res = message ("%q[]", res);
529 base = ctype_baseArrayPtr (base);
532 return (message ("%t %q", base, res));
534 else
536 return (message ("%t [%d]",
537 c->contents.farray->base,
538 (int) c->contents.farray->size));
540 case CT_ARRAY:
541 if (ctype_isArray (c->contents.base))
543 ctype base = c->contents.base;
544 cstring res = cstring_makeLiteral ("[]");
546 while (ctype_isArray (base))
548 if (ctype_isFixedArray (base))
550 res = message ("%q[%d]",
551 res, (int) ctype_getArraySize (base));
553 else
555 res = message ("%q[]", res);
558 base = ctype_baseArrayPtr (base);
561 return (message ("%t %q", base, res));
564 else
566 return (message ("%t []", c->contents.base));
568 case CT_FCN:
569 return (message ("[function (%q) returns %t]",
570 uentryList_unparseParams (c->contents.fcn->params),
571 c->contents.fcn->rval));
572 case CT_STRUCT:
573 if (cstring_isDefined (c->contents.su->name) &&
574 !cstring_isEmpty (c->contents.su->name) &&
575 !isFakeTag (c->contents.su->name))
577 return (message ("struct %s", c->contents.su->name));
579 else
581 return (message ("struct { %q }",
582 uentryList_unparseAbbrev (c->contents.su->fields)));
584 case CT_UNION:
585 if (cstring_isDefined (c->contents.su->name) &&
586 !cstring_isEmpty (c->contents.su->name) &&
587 !isFakeTag (c->contents.su->name))
589 return (message ("union %s", c->contents.su->name));
591 else
593 return (message ("union { %q }",
594 uentryList_unparseAbbrev (c->contents.su->fields)));
596 case CT_ENUM:
597 if (isFakeTag (c->contents.cenum->tag))
599 return (message ("enum { %q }",
600 enumNameList_unparseBrief (c->contents.cenum->members)));
602 else
604 return (message ("enum %s { %q }",
605 c->contents.cenum->tag,
606 enumNameList_unparseBrief (c->contents.cenum->members)));
608 case CT_CONJ:
609 if (ctbase_isAnytype (c))
611 return (cstring_makeLiteral ("<any>"));
613 else if (c->contents.conj->isExplicit || context_getFlag (FLG_SHOWALLCONJS))
615 if (!ctype_isSimple (c->contents.conj->a) ||
616 !ctype_isSimple (c->contents.conj->b))
618 return (message ("<%t> | <%t>", c->contents.conj->a, c->contents.conj->b));
620 else
622 return (message ("%t | %t", c->contents.conj->a, c->contents.conj->b));
625 else
627 return (cstring_copy (ctype_unparse (c->contents.conj->a)));
629 BADDEFAULT;
631 BADEXIT;
634 static /*@only@*/ cstring
635 ctbase_unparseDeep (ctbase c)
637 if (ctbase_isUndefined (c))
639 return cstring_makeLiteral ("<<undef>>");
642 switch (c->type)
644 case CT_UNKNOWN:
645 return cstring_makeLiteral ("?");
646 case CT_BOOL:
647 return cstring_copy (context_printBoolName ());
648 case CT_PRIM:
649 return (cprim_unparse (c->contents.prim));
650 case CT_ENUM:
651 if (cstring_isNonEmpty (c->contents.cenum->tag))
653 return (message ("enum %s { %q }",
654 c->contents.cenum->tag,
655 enumNameList_unparse (c->contents.cenum->members)));
657 else
659 return (message ("enum { %q }",
660 enumNameList_unparse (c->contents.cenum->members)));
662 case CT_USER:
663 case CT_ABST:
664 case CT_NUMABST:
665 return (usymtab_getTypeEntryName (c->contents.tid));
666 case CT_EXPFCN:
667 return (message ("<expf: %t>", c->contents.base));
668 case CT_PTR:
669 return (message ("%t *", c->contents.base));
670 case CT_FIXEDARRAY:
671 return (message ("%t [%d]", c->contents.farray->base,
672 (int) c->contents.farray->size));
673 case CT_ARRAY:
674 return (message ("%t []", c->contents.base));
675 case CT_FCN:
676 return (message ("[function (%q) returns %t]",
677 uentryList_unparse (c->contents.fcn->params),
678 c->contents.fcn->rval));
679 case CT_STRUCT:
680 return (message ("struct %s { ... } ", c->contents.su->name));
681 case CT_UNION:
682 return (message ("union %s { ... }", c->contents.su->name));
683 case CT_CONJ:
684 if (ctbase_isAnytype (c))
686 return (cstring_makeLiteral ("<any>"));
688 else
690 return (message ("%t", c->contents.conj->a));
692 BADDEFAULT;
694 BADEXIT;
697 #ifdef DEADCODE
698 static /*@only@*/ cstring
699 ctbase_unparseNotypes (ctbase c)
701 llassert (ctbase_isDefined (c));
703 switch (c->type)
705 case CT_UNKNOWN:
706 return cstring_makeLiteral ("?");
707 case CT_BOOL:
708 return cstring_copy (context_printBoolName ());
709 case CT_PRIM:
710 return (cprim_unparse (c->contents.prim));
711 case CT_ENUM:
712 if (typeId_isInvalid (c->contents.tid))
714 return cstring_makeLiteral ("enum");
716 else
718 return (message ("T#%d", c->contents.tid));
720 case CT_USER:
721 return (message ("uT#%d", c->contents.tid));
722 case CT_ABST:
723 return (message ("aT#%d", c->contents.tid));
724 case CT_NUMABST:
725 return (message ("nT#%d", c->contents.tid));
726 case CT_EXPFCN:
727 return (message ("<expf: %q >", ctbase_unparseNotypes (ctype_getCtbase (c->contents.base))));
728 case CT_PTR:
729 return (message ("%q *", ctbase_unparseNotypes (ctype_getCtbase (c->contents.base))));
730 case CT_ARRAY:
731 return (message ("%q []", ctbase_unparseNotypes (ctype_getCtbase (c->contents.base))));
732 case CT_FCN:
733 return (message ("[function (%d) returns %q]", uentryList_size (c->contents.fcn->params),
734 ctbase_unparseNotypes (ctype_getCtbase (c->contents.fcn->rval))));
735 case CT_STRUCT:
736 return (message ("struct %s", c->contents.su->name));
737 case CT_UNION:
738 return (message ("union %s", c->contents.su->name));
739 case CT_ENUMLIST:
740 return (message ("[enumlist]"));
741 case CT_CONJ:
742 if (ctbase_isAnytype (c))
744 return (cstring_makeLiteral ("<any>"));
746 else
748 return (message ("%q/%q",
749 ctbase_unparseNotypes (ctype_getCtbase (c->contents.conj->a)),
750 ctbase_unparseNotypes (ctype_getCtbase (c->contents.conj->b))));
752 BADDEFAULT;
754 BADEXIT;
756 #endif
758 static /*@only@*/ cstring
759 ctbase_unparseDeclaration (ctbase c, /*@only@*/ cstring name) /*@*/
761 if (ctbase_isUndefined (c))
763 return name;
766 switch (c->type)
768 case CT_UNKNOWN:
769 return (message ("? %q", name));
770 case CT_BOOL:
771 return (message ("%s %q", context_printBoolName (), name));
772 case CT_PRIM:
773 return (message ("%q %q", cprim_unparse (c->contents.prim), name));
774 case CT_USER:
775 case CT_ABST:
776 case CT_NUMABST:
777 return (message ("%q %q", usymtab_getTypeEntryName (c->contents.tid), name));
778 case CT_EXPFCN:
779 llcontbuglit ("ctbase_unparseDeclaration: expfcn");
780 return name;
781 case CT_PTR:
782 if (ctype_isFunction (c->contents.base))
784 return ctbase_unparseDeclaration (ctype_getCtbase (c->contents.base), name);
786 else
788 cstring s = cstring_prependChar ('*', name);
789 cstring ret = ctbase_unparseDeclaration (ctype_getCtbase (c->contents.base), s);
790 cstring_free (name);
791 return (ret);
793 case CT_FIXEDARRAY:
794 return (message ("%q[%d]",
795 ctbase_unparseDeclaration (ctype_getCtbase (c->contents.farray->base), name),
796 (int) c->contents.farray->size));
797 case CT_ARRAY:
798 return (message ("%q[]",
799 ctbase_unparseDeclaration (ctype_getCtbase (c->contents.base), name)));
800 case CT_FCN:
802 cstring s = message ("%q(%q)", name,
803 uentryList_unparseParams (c->contents.fcn->params));
805 return (ctbase_unparseDeclaration
806 (ctype_getCtbase (c->contents.fcn->rval), s));
808 case CT_STRUCT:
809 if (cstring_isDefined (c->contents.su->name) &&
810 !cstring_isEmpty (c->contents.su->name) &&
811 !isFakeTag (c->contents.su->name))
813 return (message ("struct %s %q", c->contents.su->name, name));
815 else
817 return (message ("struct { %q } %q",
818 uentryList_unparseAbbrev (c->contents.su->fields),
819 name));
821 case CT_UNION:
822 if (cstring_isDefined (c->contents.su->name) &&
823 !cstring_isEmpty (c->contents.su->name) &&
824 !isFakeTag (c->contents.su->name))
826 return (message ("union %s %q", c->contents.su->name, name));
828 else
830 return (message ("union { %q } %q",
831 uentryList_unparseAbbrev (c->contents.su->fields),
832 name));
834 case CT_ENUM:
835 if (isFakeTag (c->contents.cenum->tag))
837 return (message ("enum { %q } %q",
838 enumNameList_unparseBrief (c->contents.cenum->members),
839 name));
841 else
843 return (message ("enum %s { %q } %q",
844 c->contents.cenum->tag,
845 enumNameList_unparseBrief (c->contents.cenum->members),
846 name));
848 case CT_CONJ:
849 if (ctbase_isAnytype (c))
851 return (message ("<any> %q", name));
853 else if (c->contents.conj->isExplicit || context_getFlag (FLG_SHOWALLCONJS))
855 if (!ctype_isSimple (c->contents.conj->a) ||
856 !ctype_isSimple (c->contents.conj->b))
858 cstring name1 = cstring_copy (name);
860 return
861 (message
862 ("<%q> | <%q>",
863 ctbase_unparseDeclaration
864 (ctype_getCtbase (c->contents.conj->a), name1),
865 ctbase_unparseDeclaration
866 (ctype_getCtbase (c->contents.conj->b), name)));
868 else
870 cstring s1 = ctbase_unparseDeclaration (ctype_getCtbase (c->contents.conj->a),
871 cstring_copy (name));
872 return
873 (message ("%q | %q", s1,
874 ctbase_unparseDeclaration (ctype_getCtbase (c->contents.conj->b),
875 name)));
878 else
880 cstring_free (name);
881 return (cstring_copy (ctype_unparse (c->contents.conj->a)));
883 BADDEFAULT;
885 BADEXIT;
888 static ctbase ctbase_undump (d_char *c) /*@requires maxRead(*c) >= 2 @*/
890 ctbase res;
891 char p = **c;
893 (*c)++;
895 switch (p)
897 case '?':
898 return (ctbase_undefined);
899 case 'u':
900 return (ctbase_createUnknown ());
901 case 'b':
902 return (ctbase_createBool ());
903 case 'p':
904 res = ctbase_createPrim (cprim_fromInt (reader_getInt (c)));
905 reader_checkChar (c, '|');
906 return res;
907 case 's':
908 res = ctbase_createUser (typeId_fromInt (reader_getInt (c)));
909 reader_checkChar (c, '|');
910 return res;
911 case 'a':
912 res = ctbase_createAbstract (typeId_fromInt (reader_getInt (c)));
913 reader_checkChar (c, '|');
914 return res;
915 case 'n':
916 res = ctbase_createNumAbstract (typeId_fromInt (reader_getInt (c)));
917 reader_checkChar (c, '|');
918 return res;
919 case 't':
920 res = ctbase_makePointer (ctype_undump (c));
921 reader_checkChar (c, '|');
922 return res;
923 case 'y':
924 res = ctbase_makeArray (ctype_undump (c));
925 reader_checkChar (c, '|');
926 return res;
927 case 'F':
929 ctype ct = ctype_undump (c);
930 size_t size;
932 reader_checkChar (c, '/');
933 size = size_fromInt (reader_getInt (c));
934 reader_checkChar (c, '|');
935 return (ctbase_makeFixedArray (ct, size));
937 case 'f':
939 ctype ct;
940 char *lp = strchr (*c, '(');
942 llassertfatal (lp != NULL);
944 *lp = '\0';
945 ct = ctype_undump (c);
946 *c = lp + 1;
948 return (ctbase_makeLiveFunction (ct, uentryList_undump (c)));
950 case 'S':
952 uentryList fields;
953 ctbase ctb;
954 char *sname;
955 char *lc = strchr (*c, '{');
957 llassert (lc != NULL);
958 *lc = '\0';
960 sname = mstring_copy (*c);
962 *c = lc + 1;
964 if (*sname == '!')
966 unsigned int i;
968 i = (unsigned) atoi (sname + 1);
970 setTagNo (i);
973 fields = uentryList_undumpFields (c, g_currentloc);
975 ctb = ctbase_createStruct (cstring_fromCharsO (sname), fields);
976 return ctb;
978 case 'U':
980 char *sname;
981 char *lc = strchr (*c, '{');
983 llassert (lc != NULL);
985 *lc = '\0';
986 sname = mstring_copy (*c);
987 llassert (sname != NULL);
989 *c = lc + 1;
991 if (*sname == '!')
993 unsigned int i;
995 i = (unsigned) atoi (sname + 1);
996 setTagNo (i);
999 return (ctbase_createUnion (cstring_fromCharsO (sname),
1000 uentryList_undumpFields (c, g_currentloc)));
1002 case 'e':
1004 ctbase ret;
1005 char *sname;
1006 char *lc = strchr (*c, '{');
1008 llassert (lc != NULL);
1010 *lc = '\0';
1011 sname = mstring_copy (*c);
1012 *c = lc + 1;
1014 if (*sname == '!')
1016 unsigned int i;
1018 i = (unsigned) atoi (sname + 1);
1019 setTagNo (i);
1022 ret = ctbase_createEnum (cstring_fromCharsO (sname),
1023 enumNameList_undump (c));
1024 return ret;
1026 case 'C':
1028 bool isExplicit;
1029 ctype c1, c2;
1031 isExplicit = bool_fromInt (reader_getInt (c));
1032 reader_checkChar (c, '.');
1033 c1 = ctype_undump (c);
1034 reader_checkChar (c, '/');
1035 c2 = ctype_undump (c);
1036 reader_checkChar (c, '|');
1038 return (ctbase_makeConj (c1, c2, isExplicit));
1041 default:
1042 (*c)--;
1043 llerror (FLG_SYNTAX,
1044 message ("Bad Library line (type): %s", cstring_fromChars (*c)));
1046 /*drl bee: pbr*/ while (**c != '\0')
1048 (*c)++;
1051 return ctbase_createUnknown ();
1055 /* first letter of c encodes type: */
1056 /* u unknown */
1057 /* b bool */
1058 /* p prim */
1059 /* e enum */
1060 /* l enumList */
1061 /* s uSer */
1062 /* a abstract */
1063 /* t poinTer */
1064 /* y arraY */
1065 /* F Fixed array */
1066 /* f function */
1067 /* S structure */
1068 /* U union */
1069 /* C conj */
1071 static /*@only@*/ cstring
1072 ctbase_dump (ctbase c)
1074 if (!ctbase_isDefined (c))
1076 return cstring_makeLiteral ("?");
1079 switch (c->type)
1081 case CT_UNKNOWN:
1082 return cstring_makeLiteral ("u");
1083 case CT_BOOL:
1084 return cstring_makeLiteral ("b");
1085 case CT_PRIM:
1086 return (message ("p%d|", c->contents.prim));
1087 case CT_USER:
1088 return (message ("s%d|", usymtab_convertTypeId (c->contents.tid)));
1089 case CT_ABST:
1090 return (message ("a%d|", usymtab_convertTypeId (c->contents.tid)));
1091 case CT_NUMABST:
1092 return (message ("n%d|", usymtab_convertTypeId (c->contents.tid)));
1093 case CT_PTR:
1094 return (message ("t%q|", ctype_dump (c->contents.base)));
1095 case CT_ARRAY:
1096 return (message ("y%q|", ctype_dump (c->contents.base)));
1097 case CT_FIXEDARRAY:
1098 return (message ("F%q/%d|",
1099 ctype_dump (c->contents.farray->base),
1100 (int) c->contents.farray->size));
1101 case CT_FCN:
1102 DPRINTF (("Dump function: %s", ctbase_unparse (c)));
1103 return (message ("f%q (%q)", ctype_dump (c->contents.fcn->rval),
1104 uentryList_dumpParams (c->contents.fcn->params)));
1105 case CT_STRUCT:
1106 return (message ("S%s{%q}", c->contents.su->name,
1107 uentryList_dumpFields (c->contents.su->fields)));
1108 case CT_UNION:
1109 return (message ("U%s{%q}", c->contents.su->name,
1110 uentryList_dumpFields (c->contents.su->fields)));
1111 case CT_ENUM:
1113 cstring s;
1115 if (cstring_isNonEmpty (c->contents.cenum->tag))
1117 s = message ("e%s{%q}",
1118 c->contents.cenum->tag,
1119 enumNameList_dump (c->contents.cenum->members));
1121 else
1123 s = message ("e{%q}",
1124 enumNameList_dump (c->contents.cenum->members));
1126 return (s);
1128 case CT_CONJ:
1129 return (message ("C%d.%q/%q|",
1130 bool_toInt (c->contents.conj->isExplicit),
1131 ctype_dump (c->contents.conj->a),
1132 ctype_dump (c->contents.conj->b)));
1133 case CT_EXPFCN:
1134 /* should clean them up! */
1135 return (cstring_makeLiteral ("?"));
1136 case CT_ENUMLIST:
1137 llcontbug (message ("Cannot dump: %q", ctbase_unparse (c)));
1138 return (message ("u"));
1139 BADDEFAULT;
1142 BADEXIT;
1145 #ifdef DEADCODE
1146 static /*@only@*/ ctbase
1147 ctbase_copy (/*@notnull@*/ ctbase c)
1149 switch (c->type)
1151 case CT_UNKNOWN:
1152 return (ctbase_createUnknown ());
1153 case CT_BOOL:
1154 return (ctbase_createBool ());
1155 case CT_ENUM:
1156 return (ctbase_createEnum (cstring_copy (c->contents.cenum->tag),
1157 enumNameList_copy (c->contents.cenum->members)));
1158 case CT_PRIM:
1159 return (ctbase_createPrim (c->contents.prim));
1160 case CT_USER:
1161 return (ctbase_createUser (c->contents.tid));
1162 case CT_ABST:
1163 return (ctbase_createAbstract (c->contents.tid));
1164 case CT_NUMABST:
1165 return (ctbase_createNumAbstract (c->contents.tid));
1166 case CT_EXPFCN:
1167 return (ctbase_expectFunction (c->contents.base));
1168 case CT_PTR:
1169 return (ctbase_makePointer (c->contents.base));
1170 case CT_ARRAY:
1171 return (ctbase_makeArray (c->contents.base));
1172 case CT_FCN:
1173 return (ctbase_makeLiveFunction (c->contents.fcn->rval,
1174 uentryList_copy (c->contents.fcn->params)));
1175 case CT_STRUCT:
1176 return (ctbase_createStruct (cstring_copy (c->contents.su->name),
1177 uentryList_copy (c->contents.su->fields)));
1178 case CT_UNION:
1179 return (ctbase_createUnion (cstring_copy (c->contents.su->name),
1180 uentryList_copy (c->contents.su->fields)));
1181 case CT_CONJ:
1182 /*@i@*/ return (c); /* not a real copy for conj's */
1183 default:
1184 llbug (message ("ctbase_copy: %q", ctbase_unparse (c)));
1187 BADEXIT;
1189 #endif
1191 static enumNameList
1192 ctbase_elist (ctbase c)
1194 llassert (ctbase_isDefined (c));
1195 llassert (c->type == CT_ENUM);
1197 return (c->contents.cenum->members);
1200 static void
1201 ctbase_free (/*@only@*/ ctbase c)
1203 if (c == ctbase_bool || c == ctbase_unknown)
1205 /*@-mustfree@*/ return; /*@=mustfree@*/
1208 --nctbases;
1211 if (ctbase_isDefined (c))
1213 switch (c->type)
1215 case CT_UNKNOWN:
1216 sfree (c);
1217 break;
1218 case CT_PRIM:
1219 sfree (c);
1220 break;
1221 case CT_ENUM:
1222 sfree (c);
1223 break;
1224 case CT_ENUMLIST:
1225 /* sfree list? */
1226 sfree (c);
1227 break;
1228 case CT_USER:
1229 case CT_ABST:
1230 case CT_NUMABST:
1231 sfree (c);
1232 break;
1233 case CT_PTR:
1234 case CT_ARRAY:
1235 sfree (c);
1236 break;
1237 case CT_FCN:
1238 /* Cannot free params: uentryList_free (c->contents.fcn->params); */
1239 uentryList_freeShallow (c->contents.fcn->params);
1240 sfree (c);
1241 break;
1242 case CT_STRUCT:
1243 case CT_UNION:
1244 cstring_free (c->contents.su->name);
1245 uentryList_free (c->contents.su->fields);
1246 sfree (c);
1247 break;
1248 case CT_CONJ:
1249 /* Don't bree conj's, */
1250 break;
1251 default:
1252 sfree (c);
1253 break;
1259 ** c should be * <unknown>
1262 static /*@only@*/ ctbase
1263 ctbase_expectFunction (ctype c)
1265 ctbase f = ctbase_new ();
1267 f->type = CT_EXPFCN;
1268 f->contents.base = c;
1270 return (f);
1273 static bool
1274 ctbase_isExpectFunction (/*@notnull@*/ ctbase ct) /*@*/
1276 return (ct->type == CT_EXPFCN);
1279 static ctype
1280 ctbase_getExpectFunction (/*@notnull@*/ ctbase ct)
1282 llassert (ctbase_isExpectFunction (ct));
1283 return ct->contents.base;
1286 static bool
1287 ctbase_genMatch (ctbase c1, ctbase c2, bool force, bool arg, bool def, bool deep)
1289 ctuid c1tid, c2tid;
1291 /* undefined types never match */
1293 if (ctbase_isUndefined (c1) || ctbase_isUndefined (c2))
1294 return FALSE;
1296 /* abstract types match user types of same name */
1298 c1 = ctbase_realType (c1);
1299 c2 = ctbase_realType (c2);
1301 DPRINTF (("Matching: %s / %s", ctbase_unparse (c1),
1302 ctbase_unparse (c2)));
1304 c1tid = c1->type;
1305 c2tid = c2->type;
1307 if (c1tid == CT_CONJ)
1309 return (ctbase_genMatch (ctype_getCtbase (c1->contents.conj->a), c2,
1310 force, arg, def, deep)
1311 || ctbase_genMatch (ctype_getCtbase (c1->contents.conj->b), c2,
1312 force, arg, def, deep));
1315 if (c2tid == CT_CONJ)
1317 return (ctbase_genMatch (c1, ctype_getCtbase (c2->contents.conj->a),
1318 force, arg, def, deep)
1319 || ctbase_genMatch (c1, ctype_getCtbase (c2->contents.conj->b),
1320 force, arg, def, deep));
1324 ** if the types don't match, there are some special cases...
1327 if (c1tid != c2tid)
1329 /* unknowns match anything */
1331 if (c1tid == CT_UNKNOWN || c2tid == CT_UNKNOWN)
1333 return TRUE;
1336 if (c1tid == CT_FIXEDARRAY
1337 && (c2tid == CT_ARRAY || (!def && c2tid == CT_PTR)))
1339 if (ctype_isVoid (c2->contents.base))
1341 return (context_getFlag (FLG_ABSTVOIDP) ||
1342 (!(ctype_isRealAbstract (c1->contents.farray->base)) &&
1343 !(ctype_isRealAbstract (c2->contents.base))));
1346 return (ctbase_genMatch (ctype_getCtbase (c1->contents.farray->base),
1347 ctype_getCtbase (c2->contents.base),
1348 force, arg, def, deep));
1352 if (c2tid == CT_FIXEDARRAY
1353 && (c1tid == CT_ARRAY || (!def && c1tid == CT_PTR)))
1355 if (ctype_isVoid (c1->contents.base))
1357 return (context_getFlag (FLG_ABSTVOIDP) ||
1358 (!(ctype_isRealAbstract (c2->contents.farray->base)) &&
1359 !(ctype_isRealAbstract (c1->contents.base))));
1362 return (ctbase_genMatch (ctype_getCtbase (c1->contents.base),
1363 ctype_getCtbase (c2->contents.farray->base),
1364 force, arg, def, deep));
1367 /* evs 2000-07-25: Bool's may match user/abstract types */
1369 if ((c1tid == CT_BOOL
1370 && (c2tid == CT_PRIM && cprim_isInt (c2->contents.prim))) ||
1371 (c2tid == CT_BOOL
1372 && (c1tid == CT_PRIM && cprim_isInt (c1->contents.prim))))
1374 return (context_msgBoolInt ());
1377 if ((c1tid == CT_BOOL && (ctuid_isAnyUserType (c2tid)))) {
1378 ctype t2c = c2->contents.base;
1379 return (ctype_isBool (t2c));
1382 if ((c2tid == CT_BOOL && (ctuid_isAnyUserType (c1tid)))) {
1383 ctype t1c = c1->contents.base;
1385 return (ctype_isBool (t1c));
1388 if ((c1tid == CT_ENUM
1389 && (c2tid == CT_PRIM && cprim_isInt (c2->contents.prim))) ||
1390 (c2tid == CT_ENUM
1391 && (c1tid == CT_PRIM && cprim_isInt (c1->contents.prim))))
1393 return (context_msgEnumInt ());
1397 ** arrays and pointers...yuk!
1399 ** Considered equivalent except in definitions.
1400 ** (e.g., function parameters are equivalent)
1404 if (!def)
1406 if (ctuid_isAP (c1tid) && ctuid_isAP (c2tid))
1408 c2tid = c1tid;
1413 ** Function pointers can be removed.
1415 ** [function ..] is equivalent to [function ..] *
1418 if (c1tid == CT_PTR && c2tid == CT_FCN)
1420 if (ctype_isFunction (ctype_realType (c1->contents.base)))
1422 c1 = ctbase_realType (ctype_getCtbaseSafe (c1->contents.base));
1423 c1tid = c1->type;
1427 if (c2tid == CT_PTR && c1tid == CT_FCN)
1429 if (ctype_isFunction (ctype_realType (c2->contents.base)))
1431 c2 = ctbase_realType (ctype_getCtbaseSafe (c2->contents.base));
1432 c2tid = c2->type;
1437 ** we allow forward declarations to structures like,
1439 ** typedef struct _t *t;
1441 ** to allow,
1442 ** struct _t * to match t
1445 if (context_getFlag (FLG_FORWARDDECL))
1447 if (ctuid_isAnyUserType (c1tid))
1449 if (ctuid_isAP (c2tid))
1451 ctype ts = c2->contents.base;
1453 if (ctype_isUA (ts))
1455 typeId ttid = ctype_typeId (ts);
1456 typeId ctid = c1->contents.tid ;
1458 if (usymtab_matchForwardStruct (ctid, ttid))
1460 return TRUE;
1466 if (ctuid_isAnyUserType (c2tid))
1468 if (ctuid_isAP (c1tid))
1470 ctype ts = c1->contents.base;
1472 if (ctype_isUA (ts))
1474 typeId ttid = ctype_typeId (ts);
1475 typeId ctid = c2->contents.tid ;
1477 if (usymtab_matchForwardStruct (ctid, ttid))
1479 return TRUE;
1487 if (c1tid != c2tid)
1488 return FALSE;
1490 switch (c1tid)
1492 case CT_UNKNOWN:
1493 return (TRUE);
1494 case CT_PRIM:
1495 if (deep) {
1496 return (cprim_closeEnoughDeep (c1->contents.prim, c2->contents.prim));
1497 } else {
1498 return (cprim_closeEnough (c1->contents.prim, c2->contents.prim));
1500 case CT_BOOL:
1501 return (TRUE);
1502 case CT_ABST:
1503 case CT_NUMABST:
1504 case CT_USER:
1505 return (typeId_equal (c1->contents.tid, c2->contents.tid));
1506 case CT_ENUM:
1507 return (cstring_equal (c1->contents.cenum->tag, c2->contents.cenum->tag));
1508 case CT_PTR:
1509 if (ctype_isVoid (c1->contents.base)
1510 || (ctype_isVoid (c2->contents.base)))
1512 if (ctype_isFunction (ctype_realType (c1->contents.base))
1513 || ctype_isFunction (ctype_realType (c2->contents.base)))
1515 return (!context_getFlag (FLG_CASTFCNPTR));
1517 else
1519 return (context_getFlag (FLG_ABSTVOIDP) ||
1520 (!(ctype_isRealAbstract (c1->contents.base)) &&
1521 !(ctype_isRealAbstract (c2->contents.base))));
1524 else
1526 /* Only allow one implicit function pointer. */
1528 if (!bool_equal (ctype_isRealPointer (c1->contents.base),
1529 ctype_isRealPointer (c2->contents.base))
1530 && (ctype_isRealFunction (c1->contents.base)
1531 || ctype_isRealFunction (c2->contents.base)))
1533 return FALSE;
1536 return (ctype_genMatch (c1->contents.base,
1537 c2->contents.base, force, arg, def, TRUE));
1539 case CT_FIXEDARRAY:
1540 if (ctype_isVoid (c1->contents.farray->base)
1541 || ctype_isVoid (c2->contents.farray->base))
1542 return TRUE;
1543 return (ctype_genMatch (c1->contents.farray->base,
1544 c2->contents.farray->base,
1545 force, arg, def, deep));
1546 case CT_ARRAY:
1547 if (ctype_isVoid (c1->contents.base) || ctype_isVoid (c2->contents.base))
1548 return TRUE;
1549 return (ctype_genMatch (c1->contents.base, c2->contents.base, force, arg, def, TRUE));
1550 case CT_FCN:
1551 return (ctype_genMatch (c1->contents.fcn->rval,
1552 c2->contents.fcn->rval,
1553 force, arg, def, TRUE)
1554 && uentryList_matchParams (c1->contents.fcn->params,
1555 c2->contents.fcn->params,
1556 force, TRUE));
1557 case CT_STRUCT:
1558 case CT_UNION:
1559 DPRINTF (("Struct: %s / %s",
1560 c1->contents.su->name,
1561 c2->contents.su->name));
1563 if (isFakeTag (c1->contents.su->name)
1564 && isFakeTag (c2->contents.su->name))
1566 /* Both fake tags, check structure */
1567 if (cstring_equal (c1->contents.su->name, c2->contents.su->name))
1569 return TRUE;
1571 else
1573 return uentryList_matchFields (c1->contents.su->fields,
1574 c2->contents.su->fields);
1577 else
1579 if (!cstring_isEmpty (c1->contents.su->name))
1581 return (cstring_equal (c1->contents.su->name, c2->contents.su->name));
1583 else
1585 if (!cstring_isEmpty (c2->contents.su->name))
1587 return FALSE;
1590 llcontbuglit ("ctbase_genMatch: match fields");
1591 return (FALSE);
1594 default:
1595 llcontbug (message ("ctbase_genMatch: unknown type: %d\n", (int)c1tid));
1596 return (FALSE);
1601 ** like ctbase_match, except for conjuncts:
1602 ** modifies conjuncts to match only
1605 static bool
1606 ctbase_forceMatch (ctbase c1, ctbase c2) /*@modifies c1, c2@*/
1608 return (ctbase_genMatch (c1, c2, TRUE, FALSE, FALSE, FALSE));
1611 static bool
1612 ctbase_match (ctbase c1, ctbase c2) /*@modifies nothing@*/
1614 return (ctbase_genMatch (c1, c2, FALSE, FALSE, FALSE, FALSE));
1617 static bool
1618 ctbase_matchDef (ctbase c1, ctbase c2) /*@modifies nothing@*/
1620 return (ctbase_genMatch (c1, c2, FALSE, FALSE, TRUE, FALSE));
1623 static bool
1624 ctbase_matchArg (ctbase c1, ctbase c2)
1626 return (ctbase_genMatch (c1, c2, FALSE, TRUE, FALSE, FALSE));
1629 static /*@out@*/ /*@only@*/ /*@notnull@*/ ctbase
1630 ctbase_new (void)
1632 ctbase c = (ctbase) dmalloc (sizeof (*c));
1634 nctbases++;
1636 if (nctbases % 100 == 0 && nctbases > lastnc)
1638 llmsg (message ("ctbases: %d", nctbases));
1639 lastnc = nctbases;
1642 return (c);
1645 static /*@only@*/ ctbase
1646 ctbase_createPrim (cprim p)
1648 ctbase c = ctbase_new ();
1650 c->type = CT_PRIM;
1651 c->contents.prim = p;
1653 return (c);
1656 static /*@observer@*/ ctbase
1657 ctbase_getBool (void)
1659 /*@i@*/ return ctbase_createBool ();
1662 static ctbase
1663 ctbase_createBool (void)
1665 if (!ctbase_isDefined (ctbase_bool))
1667 ctbase_bool = ctbase_new ();
1668 ctbase_bool->type = CT_BOOL;
1669 ctbase_bool->contents.prim = CTX_BOOL;
1672 /*@-retalias@*/ /*@-globstate@*/
1673 return ctbase_bool;
1674 /*@=retalias@*/ /*@=globstate@*/
1677 static /*@only@*/ ctbase
1678 ctbase_createUser (typeId u)
1680 ctbase c = ctbase_new ();
1682 c->type = CT_USER;
1683 c->contents.tid = u;
1685 llassert (typeId_isValid (u));
1687 return (c);
1690 static /*@only@*/ ctbase
1691 ctbase_createEnum (/*@keep@*/ cstring etag, /*@keep@*/ enumNameList emembers)
1693 ctbase c = ctbase_new ();
1695 c->type = CT_ENUM;
1697 if (cstring_isUndefined (etag))
1699 llcontbuglit ("Undefined enum tag!");
1700 etag = fakeTag ();
1703 c->contents.cenum = (tenum) dmalloc (sizeof (*c->contents.cenum));
1704 c->contents.cenum->tag = etag;
1705 c->contents.cenum->members = emembers;
1707 return (c);
1710 static /*@observer@*/ cstring
1711 ctbase_enumTag (/*@notnull@*/ ctbase ct)
1713 return (ct->contents.cenum->tag);
1716 static /*@only@*/ ctbase
1717 ctbase_createAbstract (typeId u)
1719 ctbase c = ctbase_new ();
1721 c->type = CT_ABST;
1722 c->contents.tid = u;
1724 /* also check its abstract? */
1726 llassert (typeId_isValid (c->contents.tid));
1728 return (c);
1731 static /*@only@*/ ctbase
1732 ctbase_createNumAbstract (typeId u)
1734 ctbase c = ctbase_new ();
1736 c->type = CT_NUMABST;
1737 c->contents.tid = u;
1739 /* also check its abstract? */
1741 llassert (typeId_isValid (c->contents.tid));
1742 return (c);
1745 static /*@only@*/ ctbase
1746 ctbase_createUnknown (void)
1748 if (!ctbase_isDefined (ctbase_unknown))
1750 ctbase_unknown = ctbase_new ();
1751 ctbase_unknown->type = CT_UNKNOWN;
1752 ctbase_unknown->contents.prim = CTX_UNKNOWN;
1755 /*@-retalias@*/ /*@-globstate@*/
1756 return ctbase_unknown;
1757 /*@=retalias@*/ /*@=globstate@*/
1761 ** requires: result is not assigned to b
1762 ** (should copy, but no way to reclaim storage)
1765 static /*@only@*/ ctbase
1766 ctbase_makePointer (ctype b)
1768 ctbase c = ctbase_new ();
1770 c->type = CT_PTR;
1771 c->contents.base = b;
1773 return (c);
1776 static /*@only@*/ ctbase
1777 ctbase_makeArray (ctype b)
1779 ctbase c = ctbase_new ();
1781 c->type = CT_ARRAY;
1782 c->contents.base = b;
1784 return (c);
1787 static /*@notnull@*/ /*@only@*/ ctbase
1788 ctbase_makeFixedArray (ctype b, size_t size)
1790 ctbase c = ctbase_new ();
1792 c->type = CT_FIXEDARRAY;
1794 c->contents.farray = (tfixed) dmalloc (sizeof (*c->contents.farray));
1795 c->contents.farray->base = b;
1796 c->contents.farray->size = size;
1798 return (c);
1801 static ctype
1802 ctbase_makeFunction (ctype b, /*@only@*/ uentryList p)
1804 ctbase c = ctbase_new ();
1805 ctype ct;
1807 c->type = CT_FCN;
1808 c->contents.fcn = (cfcn) dmalloc (sizeof (*c->contents.fcn));
1810 if (ctype_isFunction (b)) /* was: && ctype_isPointer (b)) */
1812 ctbase ctb;
1813 ctype rval;
1815 if (ctype_isPointer (b))
1817 ctb = ctype_getCtbase (ctype_baseArrayPtr (b));
1819 else
1821 ctb = ctype_getCtbase (b);
1824 llassert (ctbase_isDefined (ctb));
1825 llassert (ctb->type == CT_FCN);
1827 rval = ctype_makeFunction (ctb->contents.fcn->rval, p);
1829 c->contents.fcn->rval = rval;
1830 c->contents.fcn->params = uentryList_copy (ctb->contents.fcn->params); /* no copy before */
1832 else
1834 c->contents.fcn->rval = b;
1835 c->contents.fcn->params = uentryList_copy (p); /* no copy before */
1836 /*@-branchstate@*/ /* p is really released on this branch */
1838 /*@=branchstate@*/
1840 ct = cttable_addComplex (c);
1841 return (ct); /* was: ctype_makePointer (ct)); */
1844 static ctype
1845 ctbase_makeNFFunction (ctype b, /*@only@*/ uentryList p)
1847 ctbase c = ctbase_new ();
1848 ctype ct;
1850 c->type = CT_FCN;
1851 c->contents.fcn = (cfcn) dmalloc (sizeof (*c->contents.fcn));
1853 if (ctype_isFunction (b)) /* was && ctype_isPointer (b)) */
1855 ctbase ctb;
1856 ctype rval;
1858 if (ctype_isPointer (b))
1860 ctb = ctype_getCtbase (ctype_baseArrayPtr (b));
1862 else
1864 ctb = ctype_getCtbase (b);
1867 llassert (ctbase_isDefined (ctb));
1868 llassert (ctb->type == CT_FCN);
1870 rval = ctype_makeNFParamsFunction (ctb->contents.fcn->rval, p);
1872 c->contents.fcn->rval = rval;
1873 c->contents.fcn->params = uentryList_copy (ctb->contents.fcn->params);
1875 else
1877 c->contents.fcn->rval = b;
1878 c->contents.fcn->params = uentryList_copy (p);
1879 /*@-branchstate@*/
1881 /*@=branchstate@*/
1883 ct = cttable_addComplex (c);
1884 return (ct); /* was: ctype_makePointer (ct)); */
1887 static /*@only@*/ ctbase
1888 ctbase_makeLiveFunction (ctype b, /*@only@*/ uentryList p)
1890 ctbase c = ctbase_new ();
1892 c->type = CT_FCN;
1894 c->contents.fcn = (cfcn) dmalloc (sizeof (*c->contents.fcn));
1895 c->contents.fcn->rval = b;
1896 c->contents.fcn->params = p;
1898 /*@-mustfree@*/ return (c); /*@=mustfree@*/
1901 static /*@observer@*/ /*@notnull@*/ ctbase
1902 ctbase_realFunction (/*@dependent@*/ /*@notnull@*/ ctbase c)
1904 ctbase res;
1906 if (c->type == CT_FCN)
1908 return c;
1911 llassert (ctbase_isFunction (c));
1913 res = ctype_getCtbase (c->contents.base);
1915 llassert (ctbase_isDefined (res));
1917 return (res);
1920 static bool
1921 ctbase_isFunction (ctbase c)
1923 llassert (c != ctbase_undefined);
1925 if (c->type == CT_FCN)
1927 return TRUE;
1929 else
1931 if (c->type == CT_PTR)
1933 ctbase fcn = ctype_getCtbase (ctbase_baseArrayPtr (c));
1935 return (ctbase_isDefined (fcn) && fcn->type == CT_FCN);
1938 return FALSE;
1942 /* doesn't copy c1 and c2 */
1944 static /*@only@*/ ctbase
1945 ctbase_makeConj (ctype c1, ctype c2, bool isExplicit)
1947 ctbase c = ctbase_new ();
1949 c->type = CT_CONJ;
1951 c->contents.conj = (tconj) dmalloc (sizeof (*c->contents.conj));
1952 c->contents.conj->a = c1;
1953 c->contents.conj->b = c2;
1954 c->contents.conj->isExplicit = isExplicit;
1956 return (c);
1959 static bool ctbase_isAnytype (/*@notnull@*/ ctbase b)
1962 ** A unknown|dne conj is a special representation for an anytype.
1965 if (b->type == CT_CONJ)
1967 /*@access ctype@*/
1968 return (b->contents.conj->a == ctype_unknown
1969 && b->contents.conj->b == ctype_dne);
1970 /*@noaccess ctype@*/
1973 return FALSE;
1976 static ctype
1977 ctbase_getConjA (/*@notnull@*/ ctbase c)
1979 llassert (c->type == CT_CONJ);
1980 return (c->contents.conj->a);
1983 static ctype
1984 ctbase_getConjB (/*@notnull@*/ ctbase c)
1986 llassert (c->type == CT_CONJ);
1987 return (c->contents.conj->b);
1990 static bool
1991 ctbase_isExplicitConj (/*@notnull@*/ ctbase c)
1993 llassert (c->type == CT_CONJ);
1994 return (c->contents.conj->isExplicit);
1997 static /*@only@*/ ctbase
1998 ctbase_createStruct (/*@only@*/ cstring n, /*@only@*/ uentryList f)
2000 ctbase c = ctbase_new ();
2002 c->type = CT_STRUCT;
2004 c->contents.su = (tsu) dmalloc (sizeof (*c->contents.su));
2005 c->contents.su->name = n;
2006 c->contents.su->fields = f;
2008 return (c);
2011 static /*@observer@*/ uentryList
2012 ctbase_getuentryList (/*@notnull@*/ ctbase c)
2014 c = ctbase_realType (c);
2016 if (!(c->type == CT_STRUCT || c->type == CT_UNION))
2017 llfatalbug (message ("ctbase_getuentryList: bad invocation: %q", ctbase_unparse (c)));
2019 return (c->contents.su->fields);
2022 static ctbase
2023 ctbase_createUnion (/*@keep@*/ cstring n, /*@only@*/ uentryList f)
2025 ctbase c = ctbase_new ();
2027 c->type = CT_UNION;
2029 c->contents.su = (tsu) dmalloc (sizeof (*c->contents.su));
2030 c->contents.su->name = n;
2031 c->contents.su->fields = f;
2033 return (c);
2036 static ctype
2037 ctbase_baseArrayPtr (/*@notnull@*/ ctbase c)
2039 ctuid ct;
2040 c = ctbase_realType (c);
2041 ct = c->type;
2043 if (ct == CT_FIXEDARRAY)
2045 return c->contents.farray->base;
2047 else
2049 llassert (ctuid_isAP (ct));
2051 return c->contents.base;
2055 static ctype
2056 ctbase_baseFunction (/*@notnull@*/ ctbase c)
2058 ctbase_fixUser (c);
2059 c = ctbase_realFunction (c);
2061 if (c->type != CT_FCN)
2063 llfatalbug (message ("ctbase_baseFunction: bad call: %q", ctbase_unparse (c)));
2066 return (c->contents.fcn->rval);
2069 static uentryList
2070 ctbase_argsFunction (/*@notnull@*/ ctbase c)
2072 ctbase_fixUser (c);
2073 c = ctbase_realFunction (c);
2075 if (c->type != CT_FCN)
2077 llfatalbug (message ("ctbase_argsFunction: bad call: %q",
2078 ctbase_unparse (c)));
2080 return (c->contents.fcn->params);
2083 static bool
2084 ctbase_baseisExpFcn (ctype c)
2086 ctbase cb;
2087 c = ctype_removePointers (c);
2089 cb = ctype_getCtbase (c);
2090 llassert (ctbase_isDefined (cb));
2092 if (cb->type == CT_FCN)
2094 c = ctype_removePointers (ctype_getReturnType (c));
2096 cb = ctype_getCtbase (c);
2097 llassert (ctbase_isDefined (cb));
2099 return (cb->type == CT_EXPFCN);
2101 return FALSE;
2105 ** ctbase_newBase behaves specially when p is a CONJ:
2107 ** c -> conj (newBase (c, p.a), p.b)
2110 static ctype
2111 ctbase_newBase (ctype c, ctype p)
2113 ctbase cb;
2115 DPRINTF (("New base: %s / %s", ctype_unparse (c), ctype_unparse (p)));
2117 if (ctype_isUndefined (c) || ctype_isUnknown (c))
2119 return p;
2122 cb = ctype_getCtbase (c);
2124 if (ctype_isConj (p))
2126 ctbase pb = ctype_getCtbase (p);
2128 llassert (ctbase_isDefined (pb));
2130 if (pb->contents.conj->isExplicit)
2132 return (ctype_makeExplicitConj (ctype_newBase (c, pb->contents.conj->a),
2133 pb->contents.conj->b));
2136 else
2138 return (ctype_makeConj (ctype_newBase (c, pb->contents.conj->a),
2139 pb->contents.conj->b));
2144 if (ctbase_baseisExpFcn (c))
2146 return (ctbase_newBaseExpFcn (c, p));
2149 llassert (ctbase_isDefined (cb));
2151 switch (cb->type)
2153 case CT_UNKNOWN:
2154 case CT_PRIM:
2155 case CT_USER:
2156 case CT_ENUM:
2157 case CT_ABST:
2158 case CT_NUMABST:
2159 case CT_STRUCT:
2160 case CT_UNION:
2161 case CT_EXPFCN:
2162 return (p);
2164 case CT_PTR:
2166 ctype ret;
2167 ctype cbn;
2169 cbn = ctbase_newBase (cb->contents.base, p);
2170 ret = ctype_makePointer (cbn);
2172 return ret;
2174 case CT_FIXEDARRAY:
2175 return (ctype_makeFixedArray (ctbase_newBase (cb->contents.farray->base, p),
2176 cb->contents.farray->size));
2177 case CT_ARRAY:
2178 return (ctype_makeArray (ctbase_newBase (cb->contents.base, p)));
2179 case CT_FCN:
2180 return (ctype_makeRawFunction (ctbase_newBase (cb->contents.fcn->rval, p),
2181 cb->contents.fcn->params));
2182 case CT_CONJ:
2183 return (ctype_makeConjAux (ctbase_newBase (cb->contents.conj->a, p),
2184 ctbase_newBase (cb->contents.conj->b, p),
2185 cb->contents.conj->isExplicit));
2186 default:
2187 llcontbug (message ("ctbase_newBase: bad ctbase: %q", ctbase_unparse (cb)));
2188 return (p);
2190 BADEXIT;
2193 static ctype
2194 ctbase_newBaseExpFcn (ctype c, ctype p)
2196 ctbase cb = ctype_getCtbase (c);
2197 ctbase tcb;
2198 ctype ret, tmpct;
2199 ctype fp = ctype_unknown;
2200 uentryList ctargs = ctype_argsFunction (c);
2203 ** okay, this is really ugly...
2205 ** pointers inside <expf> mean pointers to the function;
2206 ** pointers outside <expf> are pointers to the return value;
2207 ** because its a function there is one superfluous pointer.
2211 ** bf is a ctype, used to derived structure of cb
2214 if (!ctbase_isFunction (cb))
2215 llbuglit ("ctbase_newBaseExpFcn: expFcn -> not a function");
2217 tmpct = ctype_getBaseType (ctype_getReturnType (c));
2220 ** pointers before expfcn -> p are pointers to function, not result
2224 tcb = ctype_getCtbase (tmpct);
2226 llassert (ctbase_isDefined (tcb));
2227 tmpct = tcb->contents.base;
2230 ** record pointers to base in fp
2233 while (!ctype_isUnknown (tmpct))
2235 if (ctype_isExpFcn (tmpct)) {
2236 ctbase ttcb = ctype_getCtbase (tmpct);
2239 ** evs 2000-05-16: This is necessary to deal with function pointers in parens.
2240 ** The whole function pointer parsing is a major kludge, but it seems to work,
2241 ** and I'm only embarrassed by it when I haven't look at the C spec recently...
2244 llassert (ctbase_isDefined (ttcb));
2245 tmpct = ttcb->contents.base;
2246 llassert (!ctype_isUnknown (tmpct));
2249 switch (ctype_getCtKind (tmpct))
2251 case CTK_PTR:
2252 fp = ctype_makePointer (fp);
2253 /*@switchbreak@*/ break;
2254 case CTK_ARRAY:
2255 fp = ctype_makeArray (fp);
2256 /*@switchbreak@*/ break;
2257 case CTK_COMPLEX:
2259 ctbase fbase = ctype_getCtbase (tmpct);
2261 if (ctbase_isFunction (fbase))
2263 fp = ctype_makeFunction (fp, uentryList_copy (ctargs));
2264 ctargs = ctbase_argsFunction (fbase);
2266 else
2268 llbug
2269 (message
2270 ("ctbase_newBaseExpFcn: fixing expfunction: bad complex type: %s [base: %q]",
2271 ctype_unparse (tmpct), ctbase_unparse (fbase)));
2273 goto exitLoop;
2275 default:
2277 llcontbug
2278 (message ("ctbase_newBaseExpFcn: fixing expfunction: bad type: %s",
2279 ctype_unparse (tmpct)));
2280 goto exitLoop;
2283 tmpct = ctype_baseArrayPtr (tmpct);
2286 exitLoop:
2287 tmpct = ctype_getReturnType (c);
2290 ** pointers to expf are pointers to return value
2293 while (!ctype_isExpFcn (tmpct))
2295 switch (ctype_getCtKind (tmpct))
2297 case CTK_PTR:
2298 p = ctype_makePointer (p);
2299 /*@switchbreak@*/ break;
2300 case CTK_ARRAY:
2301 p = ctype_makeArray (p);
2302 /*@switchbreak@*/ break;
2303 case CTK_COMPLEX:
2305 ctbase fbase = ctype_getCtbase (tmpct);
2307 if (ctbase_isFunction (fbase))
2309 p = ctype_makeFunction (p, uentryList_copy (ctbase_argsFunction (fbase)));
2311 else
2313 llbug
2314 (message
2315 ("ctbase_newBaseExpFcn: fixing expfunction: bad complex type: %s",
2316 ctype_unparse (tmpct)));
2318 goto exitLoop2;
2321 default:
2323 llcontbug
2324 (message ("ctbase_newBaseExpFcn: fixing expfunction2: bad type: %t",
2325 tmpct));
2326 goto exitLoop2;
2329 tmpct = ctype_baseArrayPtr (tmpct);
2332 exitLoop2:
2335 ** pointers to fp are pointers to function type
2338 ret = ctype_makeRawFunction (p, uentryList_copy (ctargs));
2340 while (ctype_getCtKind (fp) > CTK_PLAIN)
2342 switch (ctype_getCtKind (fp))
2344 case CTK_PTR:
2345 ret = ctype_makePointer (ret);
2346 /*@switchbreak@*/ break;
2347 case CTK_ARRAY:
2348 ret = ctype_makeArray (ret);
2349 /*@switchbreak@*/ break;
2350 case CTK_COMPLEX:
2352 ctbase fbase = ctype_getCtbase (fp);
2354 if (ctbase_isFunction (fbase))
2356 ret =
2357 ctype_makeFunction (ret,
2358 uentryList_copy (ctbase_argsFunction (fbase)));
2360 else
2362 BADBRANCH;
2364 goto exitLoop3;
2367 default:
2369 llcontbug (message ("post-fixing expfunction: bad type: %t", fp));
2370 goto exitLoop3;
2373 fp = ctype_baseArrayPtr (fp);
2376 exitLoop3:
2377 return (ret);
2380 #ifdef DEADCODE
2382 ** returns lowest level base of c: plain type
2385 static /*@notnull@*/ /*@only@*/ ctbase
2386 ctbase_getBaseType (/*@notnull@*/ ctbase c)
2388 switch (c->type)
2390 case CT_UNKNOWN:
2391 case CT_PRIM:
2392 case CT_USER:
2393 case CT_ENUM:
2394 case CT_ENUMLIST:
2395 case CT_BOOL:
2396 case CT_ABST:
2397 case CT_NUMABST:
2398 case CT_FCN:
2399 case CT_STRUCT:
2400 case CT_UNION:
2401 return (ctbase_copy (c));
2403 case CT_PTR:
2404 case CT_ARRAY:
2405 return (ctbase_getBaseType (ctype_getCtbaseSafe (c->contents.base)));
2407 case CT_FIXEDARRAY:
2408 return (ctbase_getBaseType (ctype_getCtbaseSafe (c->contents.farray->base)));
2409 case CT_CONJ: /* base type of A conj branch? */
2410 return (ctbase_getBaseType (ctype_getCtbaseSafe (c->contents.conj->a)));
2411 case CT_EXPFCN:
2412 return (ctbase_copy (c));
2414 default:
2415 llfatalbug (message ("ctbase_getBaseType: bad ctbase: %q", ctbase_unparse (c)));
2418 BADEXIT;
2420 #endif
2422 static int
2423 ctbase_compare (ctbase c1, ctbase c2, bool strict)
2425 ctuid c1tid, c2tid;
2427 if (ctbase_isUndefined (c1) || ctbase_isUndefined (c2))
2429 llcontbuglit ("ctbase_compare: undefined ctbase");
2430 return -1;
2433 c1tid = c1->type;
2434 c2tid = c2->type;
2436 if (c1tid < c2tid)
2437 return -1;
2438 if (c1tid > c2tid)
2439 return 1;
2441 switch (c1tid)
2443 case CT_UNKNOWN:
2444 return 0;
2445 case CT_PRIM:
2446 return (int_compare (c1->contents.prim, c2->contents.prim));
2447 case CT_BOOL:
2448 return 0;
2449 case CT_USER:
2450 return (typeId_compare (c1->contents.tid, c2->contents.tid));
2451 case CT_ENUMLIST:
2452 return 1;
2453 case CT_ENUM: /* for now, keep like abstract */
2454 case CT_ABST:
2455 case CT_NUMABST:
2456 return (typeId_compare (c1->contents.tid, c2->contents.tid));
2457 case CT_PTR:
2458 return (ctype_compare (c1->contents.base, c2->contents.base));
2459 case CT_FIXEDARRAY:
2460 INTCOMPARERETURN (c1->contents.farray->size, c2->contents.farray->size);
2462 return (ctype_compare (c1->contents.farray->base,
2463 c2->contents.farray->base));
2464 case CT_ARRAY:
2465 return (ctype_compare (c1->contents.base, c2->contents.base));
2466 case CT_FCN:
2468 COMPARERETURN (ctype_compare (c1->contents.fcn->rval, c2->contents.fcn->rval));
2470 if (strict)
2472 return (uentryList_compareStrict (c1->contents.fcn->params,
2473 c2->contents.fcn->params));
2475 else
2477 return (uentryList_compareParams (c1->contents.fcn->params,
2478 c2->contents.fcn->params));
2481 case CT_EXPFCN:
2482 return (ctype_compare (c1->contents.base, c2->contents.base));
2483 case CT_STRUCT:
2484 case CT_UNION:
2485 /* evs 2000-07-28: this block was missing! */
2486 if (strict) {
2487 int ncmp = cstring_compare (c1->contents.su->name,
2488 c2->contents.su->name);
2490 if (ncmp != 0) {
2491 if (isFakeTag (c1->contents.su->name)
2492 && isFakeTag (c2->contents.su->name)) {
2493 ; /* If they are both fake struct tags, don't require match. */
2494 } else {
2495 return ncmp;
2500 DPRINTF (("Comparing fields: %s / %s",
2501 ctbase_unparse (c1),
2502 ctbase_unparse (c2)));
2504 return (uentryList_compareFields (c1->contents.su->fields,
2505 c2->contents.su->fields));
2506 case CT_CONJ:
2508 COMPARERETURN (ctype_compare (c1->contents.conj->a,
2509 c2->contents.conj->a));
2510 COMPARERETURN (ctype_compare (c1->contents.conj->b,
2511 c2->contents.conj->b));
2512 return (bool_compare (c1->contents.conj->isExplicit,
2513 c2->contents.conj->isExplicit));
2516 BADEXIT;
2519 static int
2520 ctbase_compareStrict (/*@notnull@*/ ctbase c1, /*@notnull@*/ ctbase c2)
2522 return (ctbase_compare (c1, c2, TRUE));
2525 static bool ctbase_equivStrict (/*@notnull@*/ ctbase c1, /*@notnull@*/ ctbase c2)
2527 return (ctbase_compareStrict (c1,c2) == 0);
2530 static bool ctbase_equiv (/*@notnull@*/ ctbase c1, /*@notnull@*/ ctbase c2)
2532 return (ctbase_compare (c1, c2, FALSE) == 0);
2535 static bool
2536 ctbase_isKind (/*@notnull@*/ ctbase c, ctuid kind)
2538 ctuid ck = c->type;
2540 if (ck == kind)
2541 return TRUE;
2543 if (ck == CT_CONJ)
2544 return (ctbase_isKind (ctype_getCtbaseSafe (c->contents.conj->a), kind) ||
2545 ctbase_isKind (ctype_getCtbaseSafe (c->contents.conj->b), kind));
2547 return FALSE;
2550 #ifdef DEADCODE
2551 static bool
2552 ctbase_isKind2 (/*@notnull@*/ ctbase c, ctuid kind1, ctuid kind2)
2554 ctuid ck = c->type;
2556 if (ck == kind1 || ck == kind2)
2557 return TRUE;
2559 if (ck == CT_CONJ)
2560 return (ctbase_isKind2 (ctype_getCtbaseSafe (c->contents.conj->a), kind1, kind2) ||
2561 ctbase_isKind2 (ctype_getCtbaseSafe (c->contents.conj->b), kind1, kind2));
2563 return FALSE;
2565 #endif
2567 static bool
2568 ctbase_isAbstract (/*@notnull@*/ ctbase c)
2570 return (c->type == CT_ABST || c->type == CT_NUMABST);
2573 static bool
2574 ctbase_isNumAbstract (/*@notnull@*/ ctbase c)
2576 return (c->type == CT_NUMABST);
2579 static bool ctbase_isUA (ctbase c)
2581 return (ctbase_isDefined (c) && (ctuid_isAnyUserType (c->type)));
2584 static bool
2585 ctbase_almostEqual (ctbase c1, ctbase c2)
2587 ctuid c1tid, c2tid;
2589 /* undefined types never match */
2591 if (ctbase_isUndefined (c1) || ctbase_isUndefined (c2))
2592 return FALSE;
2594 c1tid = c1->type;
2595 c2tid = c2->type;
2597 if (c1tid == CT_FIXEDARRAY && c2tid == CT_ARRAY)
2599 return (ctbase_almostEqual (ctype_getCtbase (c1->contents.farray->base),
2600 ctype_getCtbase (c2->contents.base)));
2603 if (c2tid == CT_FIXEDARRAY && c1tid == CT_ARRAY)
2605 return (ctbase_almostEqual (ctype_getCtbase (c1->contents.base),
2606 ctype_getCtbase (c2->contents.farray->base)));
2609 if (c1tid != c2tid)
2610 return FALSE;
2612 switch (c1tid)
2614 case CT_UNKNOWN:
2615 return TRUE;
2616 case CT_PRIM:
2617 return (cprim_equal (c1->contents.prim, c2->contents.prim));
2618 case CT_BOOL:
2619 return TRUE;
2620 case CT_ABST:
2621 case CT_NUMABST:
2622 case CT_USER:
2623 return (typeId_equal (c1->contents.tid, c2->contents.tid));
2624 case CT_ENUM:
2625 return (cstring_equal (c1->contents.cenum->tag, c2->contents.cenum->tag));
2626 case CT_PTR:
2627 return (ctype_almostEqual (c1->contents.base, c2->contents.base));
2628 case CT_FIXEDARRAY:
2629 return (ctype_almostEqual (c1->contents.farray->base,
2630 c2->contents.farray->base));
2631 case CT_ARRAY:
2632 return (ctype_almostEqual (c1->contents.base, c2->contents.base));
2633 case CT_FCN:
2634 return (ctype_almostEqual (c1->contents.fcn->rval, c2->contents.fcn->rval)
2635 && uentryList_matchParams (c1->contents.fcn->params,
2636 c2->contents.fcn->params, FALSE, TRUE));
2637 case CT_STRUCT:
2638 case CT_UNION:
2639 if (!cstring_isEmpty (c1->contents.su->name))
2641 return (cstring_equal (c1->contents.su->name, c2->contents.su->name));
2643 else
2645 if (!cstring_isEmpty (c2->contents.su->name))
2647 return FALSE;
2650 llcontbuglit ("ctbase_almostEqual: match fields");
2651 return (FALSE);
2653 default:
2654 llcontbug (message ("ctbase_almostEqual: unknown type: %d\n", (int)c1tid));
2655 return (FALSE);
2659 /*drl added July 02, 001
2660 called by ctype_getArraySize
2663 static size_t ctbase_getArraySize (ctbase ctb)
2665 /*drl 1/25/2002 fixed discovered by Jim Francis */
2666 ctbase r;
2668 llassert (ctbase_isDefined (ctb) );
2669 r = ctbase_realType (ctb);
2670 llassert (ctbase_isFixedArray(r) );
2672 return (r->contents.farray->size);
2675 static bool ctbase_isBigger (ctbase ct1, ctbase ct2)
2677 if (ct1 != NULL && ct2 != NULL
2678 && (ct1->type == CT_PRIM && ct2->type == CT_PRIM))
2680 /* Only compare sizes for primitives */
2681 cprim cp1 = ct1->contents.prim;
2682 cprim cp2 = ct2->contents.prim;
2683 int nbits1 = cprim_getExpectedBits (cp1);
2684 int nbits2 = cprim_getExpectedBits (cp2);
2686 if (nbits1 > nbits2) {
2687 return TRUE;
2688 } else {
2689 return FALSE;
2692 else
2694 return FALSE;
2698 static int ctbase_getSize (ctbase ct)
2700 if (ct == NULL)
2702 return 0;
2705 switch (ct->type)
2707 case CT_UNKNOWN:
2708 case CT_BOOL:
2709 case CT_PRIM:
2711 cprim cp = ct->contents.prim;
2712 int nbits = cprim_getExpectedBits (cp);
2713 return nbits;
2715 case CT_USER:
2716 case CT_ABST:
2717 case CT_NUMABST:
2718 case CT_EXPFCN:
2720 return 0;
2722 case CT_PTR:
2724 /* Malloc returns void *, but they are bytes. Normal void * is pointer size. */
2725 if (ctype_isVoid (ct->contents.base))
2727 return 8;
2729 else
2731 return ctype_getSize (ct->contents.base);
2734 case CT_FIXEDARRAY:
2735 case CT_ARRAY:
2736 case CT_FCN:
2737 case CT_STRUCT:
2738 case CT_UNION:
2739 case CT_ENUM:
2740 case CT_CONJ:
2741 break;
2742 BADDEFAULT;
2745 return 0;