Handle possible null character inside string literal
[splint-patched.git] / src / ctbase.i
blob24f3eaa616ffd661f347e795b755452cf64e69de
1 /* ;-*-C-*-;
2 ** vim: set syntax=c filetype=c shiftwidth=2 softtabstop=2 expandtab:
3 **
4 ** Splint - annotation-assisted static program checker
5 ** Copyright (C) 1994-2003 University of Virginia,
6 ** Massachusetts Institute of Technology
7 **
8 ** This program is free software; you can redistribute it and/or modify it
9 ** under the terms of the GNU General Public License as published by the
10 ** Free Software Foundation; either version 2 of the License, or (at your
11 ** option) any later version.
12 **
13 ** This program is distributed in the hope that it will be useful, but
14 ** WITHOUT ANY WARRANTY; without even the implied warranty of
15 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 ** General Public License for more details.
17 **
18 ** The GNU General Public License is available from http://www.gnu.org/ or
19 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
20 ** MA 02111-1307, USA.
22 ** For information on splint: splint@cs.virginia.edu
23 ** To report a bug: splint-bug@cs.virginia.edu
24 ** For more information: http://www.splint.org
27 ** ctbase.i
29 ** NOTE: This is not a stand-alone source file, but is included in ctype.c.
30 ** (This is necessary because there is no other way in C to have a
31 ** hidden scope, besides at the file level.)
34 /*@access cprim*/
36 abst_typedef /*@null@*/ struct s_ctbase *ctbase;
38 /*@function static bool ctuid_isAnyUserType (sef ctuid p_cid) @*/
40 /*@-macrofcndecl@*/ /*@-macroparams@*/
41 # define ctuid_isAnyUserType(cid) \
42 ((cid) == CT_ABST || (cid) == CT_USER || (cid) == CT_NUMABST)
43 /*@=macrofcndecl@*/ /*@=macroparams@*/
45 /*:private:*/ typedef struct {
46 ctkind kind;
47 ctbase ctbase;
48 ctype base; /* type I point to (or element of array) */
49 ctype ptr; /* type of pointer to me */
50 ctype array; /* type of array of me */
51 cstring unparse; /* unparse me, if memoized */
52 } *ctentry ;
54 typedef /*@only@*/ ctentry o_ctentry;
56 typedef struct {
57 int size;
58 int nspace;
59 /*@relnull@*/ /*@only@*/ o_ctentry *entries;
60 /* memoize matches...maybe in context? */
61 } cttable ;
63 extern bool ctentry_isBogus (/*@sef@*/ ctentry p_c) /*@*/;
64 # define ctentry_isBogus(c) \
65 ((c)->kind == CTK_INVALID || (c)->kind == CTK_DNE)
67 static cttable cttab = { 0, 0, NULL };
69 static /*@notnull@*/ /*@only@*/ ctbase ctbase_createAbstract (typeId p_u);
70 static /*@notnull@*/ /*@only@*/ ctbase ctbase_createNumAbstract (typeId p_u);
71 static /*@observer@*/ cstring ctentry_doUnparse (ctentry p_c) /*@modifies p_c@*/;
72 static /*@only@*/ ctentry
73 ctentry_make (ctkind p_ctk, /*@keep@*/ ctbase p_c, ctype p_base,
74 ctype p_ptr, ctype p_array, /*@keep@*/ cstring p_unparse);
75 static /*@only@*/ ctentry ctentry_makeNew (ctkind p_ctk, /*@only@*/ ctbase p_c);
76 static /*@only@*/ cstring ctentry_unparse (ctentry p_c) /*@*/ ;
78 static void cttable_grow (void);
79 static ctype cttable_addDerived (ctkind p_ctk, /*@keep@*/ ctbase p_cnew, ctype p_base);
80 static ctype cttable_addFull (/*@keep@*/ ctentry p_cnew);
81 static bool ctentry_isInteresting (ctentry p_c) /*@*/;
82 static /*@notnull@*/ /*@only@*/ ctbase ctbase_makeFixedArray (ctype p_b, size_t p_size) /*@*/ ;
83 static bool ctbase_isAnytype (/*@notnull@*/ ctbase p_b) /*@*/ ;
85 /*
86 ** These are file-static macros (used in ctype.c). No way to
87 ** declare them as static in C.
90 /*@-allmacros@*/ /*@-macrospec@*/ /*@-namechecks@*/
91 # define ctentry_getBase(c) ((c)->base)
92 # define ctentry_getKind(c) ((c)->kind)
93 # define ctentry_getArray(c) ((c)->array)
94 # define ctentry_getPtr(c) ((c)->ptr)
95 # define ctentry_isArray(c) ((c)->kind == CTK_ARRAY)
96 # define ctentry_isComplex(c) ((c)->kind == CTK_COMPLEX)
97 # define ctentry_isPlain(c) ((c)->kind == CTK_PLAIN)
98 # define ctentry_isPointer(c) ((c)->kind == CTK_PTR)
99 # define ctentry_setArray(c,b) ((c)->array = (b))
100 # define ctentry_setPtr(c,b) ((c)->ptr = (b))
102 # define ctbase_fixUser(c) (c = ctbase_realType(c))
103 /*@=allmacros@*/ /*@=macrospec@*/ /*@=namechecks@*/
105 static ctype cttable_addComplex (/*@notnull@*/ /*@only@*/ ctbase p_cnew);
106 static /*@observer@*/ ctbase ctype_getCtbase (ctype p_c) /*@*/ ;
107 static ctype ctype_makeConjAux (ctype p_c1, ctype p_c2, bool p_isExplicit) /*@*/ ;
108 static /*@notnull@*/ /*@observer@*/ ctbase ctype_getCtbaseSafe (ctype p_c) /*@*/ ;
109 static /*@observer@*/ ctentry ctype_getCtentry (ctype p_c) /*@*/ ;
110 static /*@observer@*/ /*@notnull@*/ ctbase
111 ctbase_realType (/*@notnull@*/ ctbase p_c) /*@*/ ;
112 static bool ctbase_isPointer (/*@notnull@*/ /*@dependent@*/ ctbase p_c) /*@*/ ;
113 static bool ctbase_isEitherArray (/*@notnull@*/ /*@dependent@*/ ctbase p_c) /*@*/ ;
114 static /*@observer@*/ enumNameList ctbase_elist (ctbase p_c) /*@*/ ;
115 static /*@only@*/ cstring ctbase_unparse (ctbase p_c) /*@*/ ;
116 static /*@only@*/ cstring ctbase_unparseDeep (ctbase p_c) /*@*/ ;
117 static void ctbase_free (/*@only@*/ ctbase p_c);
118 static /*@notnull@*/ /*@only@*/ ctbase ctbase_createPrim (cprim p_p) /*@*/ ;
119 static /*@notnull@*/ /*@only@*/ ctbase ctbase_createBool (void) /*@*/ ;
120 static /*@notnull@*/ /*@observer@*/ ctbase ctbase_getBool (void) /*@*/ ;
121 static /*@notnull@*/ /*@only@*/ ctbase ctbase_createUser (typeId p_u) /*@*/ ;
123 static /*@notnull@*/ /*@only@*/ ctbase
124 ctbase_createStruct (/*@only@*/ cstring p_n, /*@only@*/ uentryList p_f);
126 static /*@notnull@*/ /*@only@*/ ctbase
127 ctbase_createUnion (/*@keep@*/ cstring p_n, /*@only@*/ uentryList p_f);
128 static /*@notnull@*/ /*@only@*/ ctbase ctbase_createEnum (/*@keep@*/ cstring p_etag, /*@keep@*/ enumNameList p_emembers);
129 static /*@notnull@*/ /*@only@*/ ctbase ctbase_createUnknown (void);
130 static bool ctbase_match (ctbase p_c1, ctbase p_c2) /*@modifies nothing@*/;
131 static bool ctbase_matchDef (ctbase p_c1, ctbase p_c2) /*@modifies nothing@*/;
132 static bool ctbase_genMatch (ctbase p_c1, ctbase p_c2, bool p_force, bool p_arg, bool p_def, bool p_deep);
133 static bool ctbase_isAbstract (/*@notnull@*/ ctbase p_c) /*@*/ ;
134 static /*@notnull@*/ /*@only@*/ ctbase ctbase_makePointer (ctype p_b) /*@*/ ;
135 static /*@notnull@*/ /*@only@*/ ctbase ctbase_makeArray (ctype p_b) /*@*/ ;
136 static /*@notnull@*/ ctype
137 ctbase_makeFunction (ctype p_b, /*@only@*/ uentryList p_p) /*@*/ ;
138 static /*@notnull@*/ /*@observer@*/ ctbase
139 ctbase_realFunction (/*@notnull@*/ /*@dependent@*/ ctbase p_c) /*@*/ ;
140 static ctype ctbase_baseArrayPtr (/*@notnull@*/ ctbase p_c) /*@*/ ;
141 static ctype ctbase_baseFunction (/*@notnull@*/ ctbase p_c) /*@*/ ;
142 static /*@observer@*/ uentryList ctbase_argsFunction (/*@notnull@*/ ctbase p_c) /*@*/ ;
143 static /*@observer@*/ uentryList ctbase_getuentryList (/*@notnull@*/ ctbase p_c) /*@*/ ;
144 static ctype ctbase_newBase (ctype p_c, ctype p_p) /*@*/ ;
145 static ctype ctbase_newBaseExpFcn (ctype p_c, ctype p_p) /*@*/ ;
146 static bool ctbase_isFixedArray (/*@notnull@*/ ctbase p_c) /*@*/ ;
148 /*@-macroundef@*/
149 extern int cttable_lastIndex(void);
150 # define cttable_lastIndex() (cttab.size - 1)
151 /*@=macroundef@*/
153 typedef struct
155 ctype rval;
156 /*@only@*/ uentryList params;
157 } *cfcn;
159 typedef struct
161 cstring name;
162 uentryList fields;
163 } *tsu;
165 typedef struct
167 ctype a;
168 ctype b;
169 bool isExplicit;
170 } *tconj;
172 typedef struct
174 cstring tag;
175 enumNameList members;
176 } *tenum;
178 typedef struct
180 ctype base;
181 size_t size;
182 } *tfixed;
184 typedef union
186 cprim prim; /* primitive */
187 typeId tid; /* abstract, user */
188 ctype base; /* ptr, array */
189 cfcn fcn; /* function */
190 tsu su; /* struct union */
191 tenum cenum; /* enum */
192 tconj conj; /* conj */
193 tfixed farray; /* fixed array */
194 } uconts;
196 struct s_ctbase
198 ctuid type;
199 uconts contents;
202 static /*@falsenull@*/ bool ctbase_isUA (ctbase p_c) /*@*/ ;
203 static bool ctbase_isKind (/*@notnull@*/ ctbase p_c, ctuid p_kind) /*@*/ ;
204 static /*@falsenull@*/ bool ctbase_isFunction(ctbase p_c) /*@*/ ;
206 /*@constant null ctbase ctbase_undefined; @*/
207 # define ctbase_undefined ((ctbase)0)
209 static /*@owned@*/ ctbase ctbase_bool = ctbase_undefined;
210 static /*@owned@*/ ctbase ctbase_unknown = ctbase_undefined;
212 static /*@falsenull@*/ bool ctbase_isDefined (ctbase c) /*@*/
214 return ((c) != ctbase_undefined);
217 static /*@truenull@*/ bool ctbase_isUndefined (ctbase c)
219 return ((c) == ctbase_undefined);
222 static ctkind ctype_getCtKind (ctype c)
224 ctentry ce = ctype_getCtentry (c);
226 return ctentry_getKind (ce);
229 static bool ctbase_isUser (ctbase c)
231 if (ctbase_isDefined (c))
233 return (ctbase_isKind (c, CT_USER));
235 else
237 return FALSE;
241 static bool ctbase_isEnum (ctbase c)
243 if (ctbase_isDefined (c))
245 return (ctbase_isKind (c, CT_ENUM));
247 else
249 return FALSE;
253 static bool ctbase_isExpFcn (ctbase c)
255 if (ctbase_isDefined (c))
257 return (c->type == CT_EXPFCN);
259 else
261 return FALSE;
265 static /*@falsenull@*/ bool ctbase_isConj (ctbase c)
267 if (ctbase_isDefined (c))
269 return (c->type == CT_CONJ);
271 else
273 return FALSE;
277 static bool ctuid_isAP (ctuid c) /*@*/
279 return (c == CT_ARRAY || c == CT_PTR);
282 static typeId ctbase_typeId (ctbase p_c);
283 static /*@only@*/ cstring ctbase_dump (ctbase p_c);
284 static /*@only@*/ ctbase ctbase_undump (char **p_c) /*@requires maxRead(*p_c) >= 2 @*/;
285 static int ctbase_compare (ctbase p_c1, ctbase p_c2, bool p_strict);
286 static bool ctbase_matchArg (ctbase p_c1, ctbase p_c2);
287 static /*@notnull@*/ /*@only@*/ ctbase
288 ctbase_makeConj (ctype p_c1, ctype p_c2, bool p_isExplicit) /*@*/ ;
289 static ctype ctbase_getConjA (/*@notnull@*/ ctbase p_c) /*@*/ ;
290 static ctype ctbase_getConjB (/*@notnull@*/ ctbase p_c) /*@*/ ;
291 static bool ctbase_isExplicitConj (/*@notnull@*/ ctbase p_c) /*@*/ ;
292 static bool ctbase_forceMatch (ctbase p_c1, ctbase p_c2) /*@modifies p_c1, p_c2@*/ ;
293 static /*@notnull@*/ /*@only@*/ ctbase ctbase_expectFunction (ctype p_c);
294 static bool ctbase_isVoidPointer(/*@notnull@*/ /*@dependent@*/ ctbase p_c) /*@*/ ;
295 static bool ctbase_isUnion (/*@notnull@*/ /*@temp@*/ ctbase p_c) /*@*/ ;
296 static bool ctbase_isStruct (/*@notnull@*/ /*@temp@*/ ctbase p_c) /*@*/ ;
297 static /*@observer@*/ cstring ctbase_enumTag (/*@notnull@*/ ctbase p_ct) /*@*/ ;
299 static /*@out@*/ /*@notnull@*/ /*@only@*/ ctbase ctbase_new (void) /*@*/ ;
300 static int nctbases = 0;
302 static /*@notnull@*/ /*@only@*/
303 ctbase ctbase_makeLiveFunction (ctype p_b, /*@only@*/ uentryList p_p);
305 # ifdef DEADCODE
306 static bool ctbase_isUnnamedSU (ctbase c)
308 return (ctbase_isDefined (c)
309 && (ctbase_isStruct (c) || ctbase_isUnion (c))
310 && isFakeTag (c->contents.su->name));
312 # endif /* DEADCODE */
314 static /*@observer@*/ ctbase ctbase_realType (ctbase c)
316 if (ctbase_isUA (c))
318 typeId uid = ctbase_typeId (c);
320 if (usymtab_isBoolType (uid))
322 return ctbase_getBool ();
324 else
326 ctbase ret = ctype_getCtbase
327 (uentry_getRealType (usymtab_getTypeEntry (ctbase_typeId (c))));
329 llassert (ret != ctbase_undefined);
330 return ret;
333 else
335 return c;
339 static bool
340 ctbase_isVoidPointer (/*@dependent@*/ /*@notnull@*/ ctbase c)
342 ctbase r = ctbase_realType (c);
344 return (ctbase_isKind (r, CT_PTR) &&
345 ctype_isVoid (r->contents.base));
348 static bool
349 ctbase_isPointer (/*@notnull@*/ /*@dependent@*/ ctbase c)
351 ctbase r = ctbase_realType (c);
353 return (ctbase_isKind (r, CT_PTR));
356 static bool
357 ctbase_isEitherArray (/*@notnull@*/ ctbase c)
359 ctbase r = ctbase_realType (c);
361 return (ctbase_isKind (r, CT_ARRAY)
362 || ctbase_isKind (r, CT_FIXEDARRAY));
365 static bool
366 ctbase_isFixedArray (/*@notnull@*/ ctbase c)
368 ctbase r = ctbase_realType (c);
370 return (ctbase_isKind (r, CT_FIXEDARRAY));
373 static bool
374 ctbase_isStruct (/*@notnull@*/ ctbase c)
376 ctbase r = ctbase_realType (c);
378 return (ctbase_isKind (r, CT_STRUCT));
381 static bool
382 ctbase_isUnion (/*@notnull@*/ ctbase c)
384 ctbase r = ctbase_realType (c);
386 return (ctbase_isKind (r, CT_UNION));
390 ** clean this up -> typeTable should store ctype
393 #ifdef DEADCODE
394 static typeId
395 ctbase_typeBaseUid (ctbase c)
397 ctuid ct;
399 if (ctbase_isDefined (c))
401 ct = c->type;
403 if (ctuid_isAP (ct))
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));
415 else
417 llcontbuglit ("ctbase_typeBaseUid: bad call");
418 return typeId_invalid;
421 return typeId_invalid;
424 static bool
425 ctbase_isBaseUA (ctbase c)
427 ctuid ct;
429 if (ctbase_isDefined (c))
431 ct = c->type;
433 if (ctuid_isAP (ct))
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));
441 else
442 return (ct == CT_USER || ct == CT_ABST || ct == CT_NUMABST);
444 return FALSE;
446 #endif
448 static typeId
449 ctbase_typeId (ctbase c)
451 if (ctbase_isUA (c))
453 return c->contents.tid;
455 else
457 if (ctbase_isConj (c))
459 if (ctype_isUA (ctbase_getConjA (c))) {
460 return ctbase_typeId (ctype_getCtbase (ctbase_getConjA (c)));
461 } else if (ctype_isUA (ctbase_getConjB (c))) {
462 return ctbase_typeId (ctype_getCtbase (ctbase_getConjB (c)));
463 } else {
464 llcontbug (message ("ctbase_typeId: bad call: %q", ctbase_unparse (c)));
465 return typeId_invalid;
468 else
470 llcontbug (message ("ctbase_typeId: bad call: %q", ctbase_unparse (c)));
471 return typeId_invalid;
476 static /*@only@*/ cstring
477 ctbase_unparse (ctbase c)
479 if (ctbase_isUndefined (c)) {
480 return cstring_makeLiteral ("<<undef>>");
483 switch (c->type)
485 case CT_UNKNOWN:
486 return cstring_makeLiteral ("?");
487 case CT_BOOL:
488 return cstring_copy (context_printBoolName ());
489 case CT_PRIM:
490 return (cprim_unparse (c->contents.prim));
491 case CT_USER:
492 case CT_ABST:
493 case CT_NUMABST:
494 return (usymtab_getTypeEntryName (c->contents.tid));
495 case CT_EXPFCN:
496 return (message ("<expf: %t>", c->contents.base));
497 case CT_PTR:
498 /* no spaces for multiple pointers */
500 if (ctype_isPointer (c->contents.base))
502 return (cstring_appendChar (cstring_copy (ctype_unparse (c->contents.base)), '*'));
504 else
506 return (message ("%t *", c->contents.base));
508 case CT_FIXEDARRAY:
510 ** C prints out array declarations backwards, if
511 ** base is an array need to print out in reverse order.
514 if (ctype_isArray (c->contents.farray->base))
516 ctype base = c->contents.farray->base;
517 cstring res = message ("[%d]", (int) c->contents.farray->size);
519 while (ctype_isArray (base))
521 if (ctype_isFixedArray (base))
523 res = message ("%q[%d]",
524 res, (int) ctype_getArraySize (base));
526 else
528 res = message ("%q[]", res);
531 base = ctype_baseArrayPtr (base);
534 return (message ("%t %q", base, res));
536 else
538 return (message ("%t [%d]",
539 c->contents.farray->base,
540 (int) c->contents.farray->size));
542 case CT_ARRAY:
543 if (ctype_isArray (c->contents.base))
545 ctype base = c->contents.base;
546 cstring res = cstring_makeLiteral ("[]");
548 while (ctype_isArray (base))
550 if (ctype_isFixedArray (base))
552 res = message ("%q[%d]",
553 res, (int) ctype_getArraySize (base));
555 else
557 res = message ("%q[]", res);
560 base = ctype_baseArrayPtr (base);
563 return (message ("%t %q", base, res));
566 else
568 return (message ("%t []", c->contents.base));
570 case CT_FCN:
571 return (message ("[function (%q) returns %t]",
572 uentryList_unparseParams (c->contents.fcn->params),
573 c->contents.fcn->rval));
574 case CT_STRUCT:
575 if (cstring_isDefined (c->contents.su->name) &&
576 !cstring_isEmpty (c->contents.su->name) &&
577 !isFakeTag (c->contents.su->name))
579 return (message ("struct %s", c->contents.su->name));
581 else
583 return (message ("struct { %q }",
584 uentryList_unparseAbbrev (c->contents.su->fields)));
586 case CT_UNION:
587 if (cstring_isDefined (c->contents.su->name) &&
588 !cstring_isEmpty (c->contents.su->name) &&
589 !isFakeTag (c->contents.su->name))
591 return (message ("union %s", c->contents.su->name));
593 else
595 return (message ("union { %q }",
596 uentryList_unparseAbbrev (c->contents.su->fields)));
598 case CT_ENUM:
599 if (isFakeTag (c->contents.cenum->tag))
601 return (message ("enum { %q }",
602 enumNameList_unparseBrief (c->contents.cenum->members)));
604 else
606 return (message ("enum %s { %q }",
607 c->contents.cenum->tag,
608 enumNameList_unparseBrief (c->contents.cenum->members)));
610 case CT_CONJ:
611 if (ctbase_isAnytype (c))
613 return (cstring_makeLiteral ("<any>"));
615 else if (c->contents.conj->isExplicit || context_getFlag (FLG_SHOWALLCONJS))
617 if (!ctype_isSimple (c->contents.conj->a) ||
618 !ctype_isSimple (c->contents.conj->b))
620 return (message ("<%t> | <%t>", c->contents.conj->a, c->contents.conj->b));
622 else
624 return (message ("%t | %t", c->contents.conj->a, c->contents.conj->b));
627 else
629 return (cstring_copy (ctype_unparse (c->contents.conj->a)));
631 BADDEFAULT;
633 BADEXIT;
636 static /*@only@*/ cstring
637 ctbase_unparseDeep (ctbase c)
639 if (ctbase_isUndefined (c))
641 return cstring_makeLiteral ("<<undef>>");
644 switch (c->type)
646 case CT_UNKNOWN:
647 return cstring_makeLiteral ("?");
648 case CT_BOOL:
649 return cstring_copy (context_printBoolName ());
650 case CT_PRIM:
651 return (cprim_unparse (c->contents.prim));
652 case CT_ENUM:
653 if (cstring_isNonEmpty (c->contents.cenum->tag))
655 return (message ("enum %s { %q }",
656 c->contents.cenum->tag,
657 enumNameList_unparse (c->contents.cenum->members)));
659 else
661 return (message ("enum { %q }",
662 enumNameList_unparse (c->contents.cenum->members)));
664 case CT_USER:
665 case CT_ABST:
666 case CT_NUMABST:
667 return (usymtab_getTypeEntryName (c->contents.tid));
668 case CT_EXPFCN:
669 return (message ("<expf: %t>", c->contents.base));
670 case CT_PTR:
671 return (message ("%t *", c->contents.base));
672 case CT_FIXEDARRAY:
673 return (message ("%t [%d]", c->contents.farray->base,
674 (int) c->contents.farray->size));
675 case CT_ARRAY:
676 return (message ("%t []", c->contents.base));
677 case CT_FCN:
678 return (message ("[function (%q) returns %t]",
679 uentryList_unparse (c->contents.fcn->params),
680 c->contents.fcn->rval));
681 case CT_STRUCT:
682 return (message ("struct %s { ... } ", c->contents.su->name));
683 case CT_UNION:
684 return (message ("union %s { ... }", c->contents.su->name));
685 case CT_CONJ:
686 if (ctbase_isAnytype (c))
688 return (cstring_makeLiteral ("<any>"));
690 else
692 return (message ("%t", c->contents.conj->a));
694 BADDEFAULT;
696 BADEXIT;
699 #ifdef DEADCODE
700 static /*@only@*/ cstring
701 ctbase_unparseNotypes (ctbase c)
703 llassertfatal (ctbase_isDefined (c));
705 switch (c->type)
707 case CT_UNKNOWN:
708 return cstring_makeLiteral ("?");
709 case CT_BOOL:
710 return cstring_copy (context_printBoolName ());
711 case CT_PRIM:
712 return (cprim_unparse (c->contents.prim));
713 case CT_ENUM:
714 if (typeId_isInvalid (c->contents.tid))
716 return cstring_makeLiteral ("enum");
718 else
720 return (message ("T#%d", c->contents.tid));
722 case CT_USER:
723 return (message ("uT#%d", c->contents.tid));
724 case CT_ABST:
725 return (message ("aT#%d", c->contents.tid));
726 case CT_NUMABST:
727 return (message ("nT#%d", c->contents.tid));
728 case CT_EXPFCN:
729 return (message ("<expf: %q >", ctbase_unparseNotypes (ctype_getCtbase (c->contents.base))));
730 case CT_PTR:
731 return (message ("%q *", ctbase_unparseNotypes (ctype_getCtbase (c->contents.base))));
732 case CT_ARRAY:
733 return (message ("%q []", ctbase_unparseNotypes (ctype_getCtbase (c->contents.base))));
734 case CT_FCN:
735 return (message ("[function (%d) returns %q]", uentryList_size (c->contents.fcn->params),
736 ctbase_unparseNotypes (ctype_getCtbase (c->contents.fcn->rval))));
737 case CT_STRUCT:
738 return (message ("struct %s", c->contents.su->name));
739 case CT_UNION:
740 return (message ("union %s", c->contents.su->name));
741 case CT_ENUMLIST:
742 return (message ("[enumlist]"));
743 case CT_CONJ:
744 if (ctbase_isAnytype (c))
746 return (cstring_makeLiteral ("<any>"));
748 else
750 return (message ("%q/%q",
751 ctbase_unparseNotypes (ctype_getCtbase (c->contents.conj->a)),
752 ctbase_unparseNotypes (ctype_getCtbase (c->contents.conj->b))));
754 BADDEFAULT;
756 BADEXIT;
758 #endif
760 static /*@only@*/ cstring
761 ctbase_unparseDeclaration (ctbase c, /*@only@*/ cstring name) /*@*/
763 if (ctbase_isUndefined (c))
765 return name;
768 switch (c->type)
770 case CT_UNKNOWN:
771 return (message ("? %q", name));
772 case CT_BOOL:
773 return (message ("%s %q", context_printBoolName (), name));
774 case CT_PRIM:
775 return (message ("%q %q", cprim_unparse (c->contents.prim), name));
776 case CT_USER:
777 case CT_ABST:
778 case CT_NUMABST:
779 return (message ("%q %q", usymtab_getTypeEntryName (c->contents.tid), name));
780 case CT_EXPFCN:
781 llcontbuglit ("ctbase_unparseDeclaration: expfcn");
782 return name;
783 case CT_PTR:
784 if (ctype_isFunction (c->contents.base))
786 return ctbase_unparseDeclaration (ctype_getCtbase (c->contents.base), name);
788 else
790 cstring s = cstring_prependChar ('*', name);
791 cstring ret = ctbase_unparseDeclaration (ctype_getCtbase (c->contents.base), s);
792 cstring_free (name);
793 return (ret);
795 case CT_FIXEDARRAY:
796 return (message ("%q[%d]",
797 ctbase_unparseDeclaration (ctype_getCtbase (c->contents.farray->base), name),
798 (int) c->contents.farray->size));
799 case CT_ARRAY:
800 return (message ("%q[]",
801 ctbase_unparseDeclaration (ctype_getCtbase (c->contents.base), name)));
802 case CT_FCN:
804 cstring s = message ("%q(%q)", name,
805 uentryList_unparseParams (c->contents.fcn->params));
807 return (ctbase_unparseDeclaration
808 (ctype_getCtbase (c->contents.fcn->rval), s));
810 case CT_STRUCT:
811 if (cstring_isDefined (c->contents.su->name) &&
812 !cstring_isEmpty (c->contents.su->name) &&
813 !isFakeTag (c->contents.su->name))
815 return (message ("struct %s %q", c->contents.su->name, name));
817 else
819 return (message ("struct { %q } %q",
820 uentryList_unparseAbbrev (c->contents.su->fields),
821 name));
823 case CT_UNION:
824 if (cstring_isDefined (c->contents.su->name) &&
825 !cstring_isEmpty (c->contents.su->name) &&
826 !isFakeTag (c->contents.su->name))
828 return (message ("union %s %q", c->contents.su->name, name));
830 else
832 return (message ("union { %q } %q",
833 uentryList_unparseAbbrev (c->contents.su->fields),
834 name));
836 case CT_ENUM:
837 if (isFakeTag (c->contents.cenum->tag))
839 return (message ("enum { %q } %q",
840 enumNameList_unparseBrief (c->contents.cenum->members),
841 name));
843 else
845 return (message ("enum %s { %q } %q",
846 c->contents.cenum->tag,
847 enumNameList_unparseBrief (c->contents.cenum->members),
848 name));
850 case CT_CONJ:
851 if (ctbase_isAnytype (c))
853 return (message ("<any> %q", name));
855 else if (c->contents.conj->isExplicit || context_getFlag (FLG_SHOWALLCONJS))
857 if (!ctype_isSimple (c->contents.conj->a) ||
858 !ctype_isSimple (c->contents.conj->b))
860 cstring name1 = cstring_copy (name);
862 return
863 (message
864 ("<%q> | <%q>",
865 ctbase_unparseDeclaration
866 (ctype_getCtbase (c->contents.conj->a), name1),
867 ctbase_unparseDeclaration
868 (ctype_getCtbase (c->contents.conj->b), name)));
870 else
872 cstring s1 = ctbase_unparseDeclaration (ctype_getCtbase (c->contents.conj->a),
873 cstring_copy (name));
874 return
875 (message ("%q | %q", s1,
876 ctbase_unparseDeclaration (ctype_getCtbase (c->contents.conj->b),
877 name)));
880 else
882 cstring_free (name);
883 return (cstring_copy (ctype_unparse (c->contents.conj->a)));
885 BADDEFAULT;
887 BADEXIT;
890 static ctbase ctbase_undump (d_char *c) /*@requires maxRead(*c) >= 2 @*/
892 ctbase res;
893 char p = **c;
895 (*c)++;
897 switch (p)
899 case '?':
900 return (ctbase_undefined);
901 case 'u':
902 return (ctbase_createUnknown ());
903 case 'b':
904 return (ctbase_createBool ());
905 case 'p':
906 res = ctbase_createPrim (cprim_fromInt (reader_getInt (c)));
907 reader_checkChar (c, '|');
908 return res;
909 case 's':
910 res = ctbase_createUser (typeId_fromInt (reader_getInt (c)));
911 reader_checkChar (c, '|');
912 return res;
913 case 'a':
914 res = ctbase_createAbstract (typeId_fromInt (reader_getInt (c)));
915 reader_checkChar (c, '|');
916 return res;
917 case 'n':
918 res = ctbase_createNumAbstract (typeId_fromInt (reader_getInt (c)));
919 reader_checkChar (c, '|');
920 return res;
921 case 't':
922 res = ctbase_makePointer (ctype_undump (c));
923 reader_checkChar (c, '|');
924 return res;
925 case 'y':
926 res = ctbase_makeArray (ctype_undump (c));
927 reader_checkChar (c, '|');
928 return res;
929 case 'F':
931 ctype ct = ctype_undump (c);
932 size_t size;
934 reader_checkChar (c, '/');
935 size = size_fromInt (reader_getInt (c));
936 reader_checkChar (c, '|');
937 return (ctbase_makeFixedArray (ct, size));
939 case 'f':
941 ctype ct;
942 char *lp = strchr (*c, '(');
944 llassertfatal (lp != NULL);
946 *lp = '\0';
947 ct = ctype_undump (c);
948 *c = lp + 1;
950 return (ctbase_makeLiveFunction (ct, uentryList_undump (c)));
952 case 'S':
954 uentryList fields;
955 ctbase ctb;
956 char *sname;
957 char *lc = strchr (*c, '{');
959 llassertfatal (lc != NULL);
960 *lc = '\0';
962 sname = mstring_copy (*c);
964 *c = lc + 1;
966 if (*sname == '!')
968 unsigned int i;
970 i = (unsigned) atoi (sname + 1);
972 setTagNo (i);
975 fields = uentryList_undumpFields (c, g_currentloc);
977 ctb = ctbase_createStruct (cstring_fromCharsO (sname), fields);
978 return ctb;
980 case 'U':
982 char *sname;
983 char *lc = strchr (*c, '{');
985 llassertfatal (lc != NULL);
987 *lc = '\0';
988 sname = mstring_copy (*c);
989 llassertfatal (sname != NULL);
991 *c = lc + 1;
993 if (*sname == '!')
995 unsigned int i;
997 i = (unsigned) atoi (sname + 1);
998 setTagNo (i);
1001 return (ctbase_createUnion (cstring_fromCharsO (sname),
1002 uentryList_undumpFields (c, g_currentloc)));
1004 case 'e':
1006 ctbase ret;
1007 char *sname;
1008 char *lc = strchr (*c, '{');
1010 llassertfatal (lc != NULL);
1012 *lc = '\0';
1013 sname = mstring_copy (*c);
1014 *c = lc + 1;
1016 if (*sname == '!')
1018 unsigned int i;
1020 i = (unsigned) atoi (sname + 1);
1021 setTagNo (i);
1024 ret = ctbase_createEnum (cstring_fromCharsO (sname),
1025 enumNameList_undump (c));
1026 return ret;
1028 case 'C':
1030 bool isExplicit;
1031 ctype c1, c2;
1033 isExplicit = bool_fromInt (reader_getInt (c));
1034 reader_checkChar (c, '.');
1035 c1 = ctype_undump (c);
1036 reader_checkChar (c, '/');
1037 c2 = ctype_undump (c);
1038 reader_checkChar (c, '|');
1040 return (ctbase_makeConj (c1, c2, isExplicit));
1043 default:
1044 (*c)--;
1045 llerror (FLG_SYNTAX,
1046 message ("Bad Library line (type): %s", cstring_fromChars (*c)));
1048 /*drl bee: pbr*/ while (**c != '\0')
1050 (*c)++;
1053 return ctbase_createUnknown ();
1057 /* first letter of c encodes type: */
1058 /* u unknown */
1059 /* b bool */
1060 /* p prim */
1061 /* e enum */
1062 /* l enumList */
1063 /* s uSer */
1064 /* a abstract */
1065 /* t poinTer */
1066 /* y arraY */
1067 /* F Fixed array */
1068 /* f function */
1069 /* S structure */
1070 /* U union */
1071 /* C conj */
1073 static /*@only@*/ cstring
1074 ctbase_dump (ctbase c)
1076 if (!ctbase_isDefined (c))
1078 return cstring_makeLiteral ("?");
1081 switch (c->type)
1083 case CT_UNKNOWN:
1084 return cstring_makeLiteral ("u");
1085 case CT_BOOL:
1086 return cstring_makeLiteral ("b");
1087 case CT_PRIM:
1088 return (message ("p%d|", c->contents.prim));
1089 case CT_USER:
1090 return (message ("s%d|", usymtab_convertTypeId (c->contents.tid)));
1091 case CT_ABST:
1092 return (message ("a%d|", usymtab_convertTypeId (c->contents.tid)));
1093 case CT_NUMABST:
1094 return (message ("n%d|", usymtab_convertTypeId (c->contents.tid)));
1095 case CT_PTR:
1096 return (message ("t%q|", ctype_dump (c->contents.base)));
1097 case CT_ARRAY:
1098 return (message ("y%q|", ctype_dump (c->contents.base)));
1099 case CT_FIXEDARRAY:
1100 return (message ("F%q/%d|",
1101 ctype_dump (c->contents.farray->base),
1102 (int) c->contents.farray->size));
1103 case CT_FCN:
1104 DPRINTF (("Dump function: %s", ctbase_unparse (c)));
1105 return (message ("f%q (%q)", ctype_dump (c->contents.fcn->rval),
1106 uentryList_dumpParams (c->contents.fcn->params)));
1107 case CT_STRUCT:
1108 return (message ("S%s{%q}", c->contents.su->name,
1109 uentryList_dumpFields (c->contents.su->fields)));
1110 case CT_UNION:
1111 return (message ("U%s{%q}", c->contents.su->name,
1112 uentryList_dumpFields (c->contents.su->fields)));
1113 case CT_ENUM:
1115 cstring s;
1117 if (cstring_isNonEmpty (c->contents.cenum->tag))
1119 s = message ("e%s{%q}",
1120 c->contents.cenum->tag,
1121 enumNameList_dump (c->contents.cenum->members));
1123 else
1125 s = message ("e{%q}",
1126 enumNameList_dump (c->contents.cenum->members));
1128 return (s);
1130 case CT_CONJ:
1131 return (message ("C%d.%q/%q|",
1132 bool_toInt (c->contents.conj->isExplicit),
1133 ctype_dump (c->contents.conj->a),
1134 ctype_dump (c->contents.conj->b)));
1135 case CT_EXPFCN:
1136 /* should clean them up! */
1137 return (cstring_makeLiteral ("?"));
1138 case CT_ENUMLIST:
1139 llcontbug (message ("Cannot dump: %q", ctbase_unparse (c)));
1140 return (message ("u"));
1141 BADDEFAULT;
1144 BADEXIT;
1147 #ifdef DEADCODE
1148 static /*@only@*/ ctbase
1149 ctbase_copy (/*@notnull@*/ ctbase c)
1151 switch (c->type)
1153 case CT_UNKNOWN:
1154 return (ctbase_createUnknown ());
1155 case CT_BOOL:
1156 return (ctbase_createBool ());
1157 case CT_ENUM:
1158 return (ctbase_createEnum (cstring_copy (c->contents.cenum->tag),
1159 enumNameList_copy (c->contents.cenum->members)));
1160 case CT_PRIM:
1161 return (ctbase_createPrim (c->contents.prim));
1162 case CT_USER:
1163 return (ctbase_createUser (c->contents.tid));
1164 case CT_ABST:
1165 return (ctbase_createAbstract (c->contents.tid));
1166 case CT_NUMABST:
1167 return (ctbase_createNumAbstract (c->contents.tid));
1168 case CT_EXPFCN:
1169 return (ctbase_expectFunction (c->contents.base));
1170 case CT_PTR:
1171 return (ctbase_makePointer (c->contents.base));
1172 case CT_ARRAY:
1173 return (ctbase_makeArray (c->contents.base));
1174 case CT_FCN:
1175 return (ctbase_makeLiveFunction (c->contents.fcn->rval,
1176 uentryList_copy (c->contents.fcn->params)));
1177 case CT_STRUCT:
1178 return (ctbase_createStruct (cstring_copy (c->contents.su->name),
1179 uentryList_copy (c->contents.su->fields)));
1180 case CT_UNION:
1181 return (ctbase_createUnion (cstring_copy (c->contents.su->name),
1182 uentryList_copy (c->contents.su->fields)));
1183 case CT_CONJ:
1184 /*@i@*/ return (c); /* not a real copy for conj's */
1185 default:
1186 llbug (message ("ctbase_copy: %q", ctbase_unparse (c)));
1189 BADEXIT;
1191 #endif
1193 static enumNameList
1194 ctbase_elist (ctbase c)
1196 llassertfatal (ctbase_isDefined (c));
1197 llassert (c->type == CT_ENUM);
1199 return (c->contents.cenum->members);
1202 static void
1203 ctbase_free (/*@only@*/ ctbase c)
1205 if (c == ctbase_bool || c == ctbase_unknown)
1207 /*@-mustfree@*/ return; /*@=mustfree@*/
1210 --nctbases;
1213 if (ctbase_isDefined (c))
1215 switch (c->type)
1217 case CT_UNKNOWN:
1218 sfree (c);
1219 break;
1220 case CT_PRIM:
1221 sfree (c);
1222 break;
1223 case CT_ENUM:
1224 sfree (c);
1225 break;
1226 case CT_ENUMLIST:
1227 /* sfree list? */
1228 sfree (c);
1229 break;
1230 case CT_USER:
1231 case CT_ABST:
1232 case CT_NUMABST:
1233 sfree (c);
1234 break;
1235 case CT_PTR:
1236 case CT_ARRAY:
1237 sfree (c);
1238 break;
1239 case CT_FCN:
1240 uentryList_free (c->contents.fcn->params);
1241 sfree (c);
1242 break;
1243 case CT_STRUCT:
1244 case CT_UNION:
1245 cstring_free (c->contents.su->name);
1246 uentryList_free (c->contents.su->fields);
1247 sfree (c);
1248 break;
1249 case CT_CONJ:
1250 /* Don't free conj's, */
1251 break;
1252 default:
1253 sfree (c);
1254 break;
1260 ** c should be * <unknown>
1263 static /*@only@*/ ctbase
1264 ctbase_expectFunction (ctype c)
1266 ctbase f = ctbase_new ();
1268 f->type = CT_EXPFCN;
1269 f->contents.base = c;
1271 return (f);
1274 static ctype
1275 ctbase_getExpectFunction (/*@notnull@*/ ctbase ct)
1277 llassert (ct->type == CT_EXPFCN);
1278 return ct->contents.base;
1281 static bool
1282 ctbase_genMatch (ctbase c1, ctbase c2, bool force, bool arg, bool def, bool deep)
1284 ctuid c1tid, c2tid;
1286 /* undefined types never match */
1288 if (ctbase_isUndefined (c1) || ctbase_isUndefined (c2))
1289 return FALSE;
1291 /* abstract types match user types of same name */
1293 c1 = ctbase_realType (c1);
1294 c2 = ctbase_realType (c2);
1296 DPRINTF (("Matching: %s / %s", ctbase_unparse (c1),
1297 ctbase_unparse (c2)));
1299 c1tid = c1->type;
1300 c2tid = c2->type;
1302 if (c1tid == CT_CONJ)
1304 return (ctbase_genMatch (ctype_getCtbase (c1->contents.conj->a), c2,
1305 force, arg, def, deep)
1306 || ctbase_genMatch (ctype_getCtbase (c1->contents.conj->b), c2,
1307 force, arg, def, deep));
1310 if (c2tid == CT_CONJ)
1312 return (ctbase_genMatch (c1, ctype_getCtbase (c2->contents.conj->a),
1313 force, arg, def, deep)
1314 || ctbase_genMatch (c1, ctype_getCtbase (c2->contents.conj->b),
1315 force, arg, def, deep));
1319 ** if the types don't match, there are some special cases...
1322 if (c1tid != c2tid)
1324 /* unknowns match anything */
1326 if (c1tid == CT_UNKNOWN || c2tid == CT_UNKNOWN)
1328 return TRUE;
1331 if (c1tid == CT_FIXEDARRAY
1332 && (c2tid == CT_ARRAY || (!def && c2tid == CT_PTR)))
1334 if (ctype_isVoid (c2->contents.base))
1336 return (context_getFlag (FLG_ABSTVOIDP) ||
1337 (!(ctype_isRealAbstract (c1->contents.farray->base)) &&
1338 !(ctype_isRealAbstract (c2->contents.base))));
1341 return (ctbase_genMatch (ctype_getCtbase (c1->contents.farray->base),
1342 ctype_getCtbase (c2->contents.base),
1343 force, arg, def, deep));
1347 if (c2tid == CT_FIXEDARRAY
1348 && (c1tid == CT_ARRAY || (!def && c1tid == CT_PTR)))
1350 if (ctype_isVoid (c1->contents.base))
1352 return (context_getFlag (FLG_ABSTVOIDP) ||
1353 (!(ctype_isRealAbstract (c2->contents.farray->base)) &&
1354 !(ctype_isRealAbstract (c1->contents.base))));
1357 return (ctbase_genMatch (ctype_getCtbase (c1->contents.base),
1358 ctype_getCtbase (c2->contents.farray->base),
1359 force, arg, def, deep));
1362 /* evs 2000-07-25: Bool's may match user/abstract types */
1364 if ((c1tid == CT_BOOL
1365 && (c2tid == CT_PRIM && cprim_isInt (c2->contents.prim))) ||
1366 (c2tid == CT_BOOL
1367 && (c1tid == CT_PRIM && cprim_isInt (c1->contents.prim))))
1369 return (context_msgBoolInt ());
1372 if ((c1tid == CT_BOOL && (ctuid_isAnyUserType (c2tid)))) {
1373 ctype t2c = c2->contents.base;
1374 return (ctype_isBool (t2c));
1377 if ((c2tid == CT_BOOL && (ctuid_isAnyUserType (c1tid)))) {
1378 ctype t1c = c1->contents.base;
1380 return (ctype_isBool (t1c));
1383 if ((c1tid == CT_ENUM
1384 && (c2tid == CT_PRIM && cprim_isInt (c2->contents.prim))) ||
1385 (c2tid == CT_ENUM
1386 && (c1tid == CT_PRIM && cprim_isInt (c1->contents.prim))))
1388 return (context_msgEnumInt ());
1392 ** arrays and pointers...yuk!
1394 ** Considered equivalent except in definitions.
1395 ** (e.g., function parameters are equivalent)
1399 if (!def)
1401 if (ctuid_isAP (c1tid) && ctuid_isAP (c2tid))
1403 c2tid = c1tid;
1408 ** Function pointers can be removed.
1410 ** [function ..] is equivalent to [function ..] *
1413 if (c1tid == CT_PTR && c2tid == CT_FCN)
1415 if (ctype_isFunction (ctype_realType (c1->contents.base)))
1417 c1 = ctbase_realType (ctype_getCtbaseSafe (c1->contents.base));
1418 c1tid = c1->type;
1422 if (c2tid == CT_PTR && c1tid == CT_FCN)
1424 if (ctype_isFunction (ctype_realType (c2->contents.base)))
1426 c2 = ctbase_realType (ctype_getCtbaseSafe (c2->contents.base));
1427 c2tid = c2->type;
1432 ** we allow forward declarations to structures like,
1434 ** typedef struct _t *t;
1436 ** to allow,
1437 ** struct _t * to match t
1440 if (context_getFlag (FLG_FORWARDDECL))
1442 if (ctuid_isAnyUserType (c1tid))
1444 if (ctuid_isAP (c2tid))
1446 ctype ts = c2->contents.base;
1448 if (ctype_isUA (ts))
1450 typeId ttid = ctype_typeId (ts);
1451 typeId ctid = c1->contents.tid ;
1453 if (usymtab_matchForwardStruct (ctid, ttid))
1455 return TRUE;
1461 if (ctuid_isAnyUserType (c2tid))
1463 if (ctuid_isAP (c1tid))
1465 ctype ts = c1->contents.base;
1467 if (ctype_isUA (ts))
1469 typeId ttid = ctype_typeId (ts);
1470 typeId ctid = c2->contents.tid ;
1472 if (usymtab_matchForwardStruct (ctid, ttid))
1474 return TRUE;
1482 if (c1tid != c2tid)
1483 return FALSE;
1485 switch (c1tid)
1487 case CT_UNKNOWN:
1488 return (TRUE);
1489 case CT_PRIM:
1490 if (deep) {
1491 return (cprim_closeEnoughDeep (c1->contents.prim, c2->contents.prim));
1492 } else {
1493 return (cprim_closeEnough (c1->contents.prim, c2->contents.prim));
1495 case CT_BOOL:
1496 return (TRUE);
1497 case CT_ABST:
1498 case CT_NUMABST:
1499 case CT_USER:
1500 return (typeId_equal (c1->contents.tid, c2->contents.tid));
1501 case CT_ENUM:
1502 return (cstring_equal (c1->contents.cenum->tag, c2->contents.cenum->tag));
1503 case CT_PTR:
1504 if (ctype_isVoid (c1->contents.base)
1505 || (ctype_isVoid (c2->contents.base)))
1507 if (ctype_isFunction (ctype_realType (c1->contents.base))
1508 || ctype_isFunction (ctype_realType (c2->contents.base)))
1510 return (!context_getFlag (FLG_CASTFCNPTR));
1512 else
1514 return (context_getFlag (FLG_ABSTVOIDP) ||
1515 (!(ctype_isRealAbstract (c1->contents.base)) &&
1516 !(ctype_isRealAbstract (c2->contents.base))));
1519 else
1521 /* Only allow one implicit function pointer. */
1523 if (!bool_equal (ctype_isRealPointer (c1->contents.base),
1524 ctype_isRealPointer (c2->contents.base))
1525 && (ctype_isRealFunction (c1->contents.base)
1526 || ctype_isRealFunction (c2->contents.base)))
1528 return FALSE;
1531 return (ctype_genMatch (c1->contents.base,
1532 c2->contents.base, force, arg, def, TRUE));
1534 case CT_FIXEDARRAY:
1535 if (ctype_isVoid (c1->contents.farray->base)
1536 || ctype_isVoid (c2->contents.farray->base))
1537 return TRUE;
1538 return (ctype_genMatch (c1->contents.farray->base,
1539 c2->contents.farray->base,
1540 force, arg, def, deep));
1541 case CT_ARRAY:
1542 if (ctype_isVoid (c1->contents.base) || ctype_isVoid (c2->contents.base))
1543 return TRUE;
1544 return (ctype_genMatch (c1->contents.base, c2->contents.base, force, arg, def, TRUE));
1545 case CT_FCN:
1546 return (ctype_genMatch (c1->contents.fcn->rval,
1547 c2->contents.fcn->rval,
1548 force, arg, def, TRUE)
1549 && uentryList_matchParams (c1->contents.fcn->params,
1550 c2->contents.fcn->params,
1551 force, TRUE));
1552 case CT_STRUCT:
1553 case CT_UNION:
1554 DPRINTF (("Struct: %s / %s",
1555 c1->contents.su->name,
1556 c2->contents.su->name));
1558 if (isFakeTag (c1->contents.su->name)
1559 && isFakeTag (c2->contents.su->name))
1561 /* Both fake tags, check structure */
1562 if (cstring_equal (c1->contents.su->name, c2->contents.su->name))
1564 return TRUE;
1566 else
1568 return uentryList_matchFields (c1->contents.su->fields,
1569 c2->contents.su->fields);
1572 else
1574 if (!cstring_isEmpty (c1->contents.su->name))
1576 return (cstring_equal (c1->contents.su->name, c2->contents.su->name));
1578 else
1580 if (!cstring_isEmpty (c2->contents.su->name))
1582 return FALSE;
1585 llcontbuglit ("ctbase_genMatch: match fields");
1586 return (FALSE);
1589 default:
1590 llcontbug (message ("ctbase_genMatch: unknown type: %d\n", (int)c1tid));
1591 return (FALSE);
1596 ** like ctbase_match, except for conjuncts:
1597 ** modifies conjuncts to match only
1600 static bool
1601 ctbase_forceMatch (ctbase c1, ctbase c2) /*@modifies c1, c2@*/
1603 return (ctbase_genMatch (c1, c2, TRUE, FALSE, FALSE, FALSE));
1606 static bool
1607 ctbase_match (ctbase c1, ctbase c2) /*@modifies nothing@*/
1609 return (ctbase_genMatch (c1, c2, FALSE, FALSE, FALSE, FALSE));
1612 static bool
1613 ctbase_matchDef (ctbase c1, ctbase c2) /*@modifies nothing@*/
1615 return (ctbase_genMatch (c1, c2, FALSE, FALSE, TRUE, FALSE));
1618 static bool
1619 ctbase_matchArg (ctbase c1, ctbase c2)
1621 return (ctbase_genMatch (c1, c2, FALSE, TRUE, FALSE, FALSE));
1624 static /*@out@*/ /*@only@*/ /*@notnull@*/ ctbase
1625 ctbase_new (void)
1627 ctbase c = (ctbase) dmalloc (sizeof (*c));
1629 nctbases++;
1631 if (nctbases % 100 == 0 && nctbases > lastnc)
1633 llmsg (message ("ctbases: %d", nctbases));
1634 lastnc = nctbases;
1637 return (c);
1640 static /*@only@*/ ctbase
1641 ctbase_createPrim (cprim p)
1643 ctbase c = ctbase_new ();
1645 c->type = CT_PRIM;
1646 c->contents.prim = p;
1648 return (c);
1651 static /*@observer@*/ ctbase
1652 ctbase_getBool (void)
1654 /*@i@*/ return ctbase_createBool ();
1657 static ctbase
1658 ctbase_createBool (void)
1660 if (!ctbase_isDefined (ctbase_bool))
1662 ctbase_bool = ctbase_new ();
1663 ctbase_bool->type = CT_BOOL;
1664 ctbase_bool->contents.prim = CTX_BOOL;
1667 /*@-retalias@*/ /*@-globstate@*/
1668 return ctbase_bool;
1669 /*@=retalias@*/ /*@=globstate@*/
1672 static /*@only@*/ ctbase
1673 ctbase_createUser (typeId u)
1675 ctbase c = ctbase_new ();
1677 c->type = CT_USER;
1678 c->contents.tid = u;
1680 llassert (typeId_isValid (u));
1682 return (c);
1685 static /*@only@*/ ctbase
1686 ctbase_createEnum (/*@keep@*/ cstring etag, /*@keep@*/ enumNameList emembers)
1688 ctbase c = ctbase_new ();
1690 c->type = CT_ENUM;
1692 if (cstring_isUndefined (etag))
1694 llcontbuglit ("Undefined enum tag!");
1695 etag = fakeTag ();
1698 c->contents.cenum = (tenum) dmalloc (sizeof (*c->contents.cenum));
1699 c->contents.cenum->tag = etag;
1700 c->contents.cenum->members = emembers;
1702 return (c);
1705 static /*@observer@*/ cstring
1706 ctbase_enumTag (/*@notnull@*/ ctbase ct)
1708 return (ct->contents.cenum->tag);
1711 static /*@only@*/ ctbase
1712 ctbase_createAbstract (typeId u)
1714 ctbase c = ctbase_new ();
1716 c->type = CT_ABST;
1717 c->contents.tid = u;
1719 /* also check its abstract? */
1721 llassert (typeId_isValid (c->contents.tid));
1723 return (c);
1726 static /*@only@*/ ctbase
1727 ctbase_createNumAbstract (typeId u)
1729 ctbase c = ctbase_new ();
1731 c->type = CT_NUMABST;
1732 c->contents.tid = u;
1734 /* also check its abstract? */
1736 llassert (typeId_isValid (c->contents.tid));
1737 return (c);
1740 static /*@only@*/ ctbase
1741 ctbase_createUnknown (void)
1743 if (!ctbase_isDefined (ctbase_unknown))
1745 ctbase_unknown = ctbase_new ();
1746 ctbase_unknown->type = CT_UNKNOWN;
1747 ctbase_unknown->contents.prim = CTX_UNKNOWN;
1750 /*@-retalias@*/ /*@-globstate@*/
1751 return ctbase_unknown;
1752 /*@=retalias@*/ /*@=globstate@*/
1756 ** requires: result is not assigned to b
1757 ** (should copy, but no way to reclaim storage)
1760 static /*@only@*/ ctbase
1761 ctbase_makePointer (ctype b)
1763 ctbase c = ctbase_new ();
1765 c->type = CT_PTR;
1766 c->contents.base = b;
1768 return (c);
1771 static /*@only@*/ ctbase
1772 ctbase_makeArray (ctype b)
1774 ctbase c = ctbase_new ();
1776 c->type = CT_ARRAY;
1777 c->contents.base = b;
1779 return (c);
1782 static /*@notnull@*/ /*@only@*/ ctbase
1783 ctbase_makeFixedArray (ctype b, size_t size)
1785 ctbase c = ctbase_new ();
1787 c->type = CT_FIXEDARRAY;
1789 c->contents.farray = (tfixed) dmalloc (sizeof (*c->contents.farray));
1790 c->contents.farray->base = b;
1791 c->contents.farray->size = size;
1793 return (c);
1796 static ctype
1797 ctbase_makeFunction (ctype b, /*@only@*/ uentryList p)
1799 ctbase c = ctbase_new ();
1800 ctype ct;
1802 c->type = CT_FCN;
1803 c->contents.fcn = (cfcn) dmalloc (sizeof (*c->contents.fcn));
1805 if (ctype_isFunction (b)) /* was: && ctype_isPointer (b)) */
1807 ctbase ctb;
1808 ctype rval;
1810 if (ctype_isPointer (b))
1812 ctb = ctype_getCtbase (ctype_baseArrayPtr (b));
1814 else
1816 ctb = ctype_getCtbase (b);
1819 llassertfatal (ctbase_isDefined (ctb));
1820 llassert (ctb->type == CT_FCN);
1822 rval = ctype_makeFunction (ctb->contents.fcn->rval, p);
1824 c->contents.fcn->rval = rval;
1825 c->contents.fcn->params = uentryList_copy (ctb->contents.fcn->params); /* no copy before */
1827 else
1829 c->contents.fcn->rval = b;
1830 c->contents.fcn->params = uentryList_copy (p); /* no copy before */
1831 /*@-branchstate@*/ /* p is really released on this branch */
1833 /*@=branchstate@*/
1835 ct = cttable_addComplex (c);
1836 return (ct); /* was: ctype_makePointer (ct)); */
1839 static ctype
1840 ctbase_makeNFFunction (ctype b, /*@only@*/ uentryList p)
1842 ctbase c = ctbase_new ();
1843 ctype ct;
1845 c->type = CT_FCN;
1846 c->contents.fcn = (cfcn) dmalloc (sizeof (*c->contents.fcn));
1848 if (ctype_isFunction (b)) /* was && ctype_isPointer (b)) */
1850 ctbase ctb;
1851 ctype rval;
1853 if (ctype_isPointer (b))
1855 ctb = ctype_getCtbase (ctype_baseArrayPtr (b));
1857 else
1859 ctb = ctype_getCtbase (b);
1862 llassertfatal (ctbase_isDefined (ctb));
1863 llassert (ctb->type == CT_FCN);
1865 rval = ctype_makeNFParamsFunction (ctb->contents.fcn->rval, p);
1867 c->contents.fcn->rval = rval;
1868 c->contents.fcn->params = uentryList_copy (ctb->contents.fcn->params);
1870 else
1872 c->contents.fcn->rval = b;
1873 c->contents.fcn->params = uentryList_copy (p);
1874 /*@-branchstate@*/
1876 /*@=branchstate@*/
1878 ct = cttable_addComplex (c);
1879 return (ct); /* was: ctype_makePointer (ct)); */
1882 static /*@only@*/ ctbase
1883 ctbase_makeLiveFunction (ctype b, /*@only@*/ uentryList p)
1885 ctbase c = ctbase_new ();
1887 c->type = CT_FCN;
1889 c->contents.fcn = (cfcn) dmalloc (sizeof (*c->contents.fcn));
1890 c->contents.fcn->rval = b;
1891 c->contents.fcn->params = p;
1893 /*@-mustfree@*/ return (c); /*@=mustfree@*/
1896 static /*@observer@*/ /*@notnull@*/ ctbase
1897 ctbase_realFunction (/*@dependent@*/ /*@notnull@*/ ctbase c)
1899 ctbase res;
1901 llassertfatal (ctbase_isFunction (c));
1903 if (c->type == CT_FCN)
1905 return c;
1908 res = ctype_getCtbase (ctbase_baseArrayPtr (c));
1909 llassert (ctbase_isDefined (res));
1911 if (ctbase_isUA (res))
1913 res = ctbase_realFunction (ctbase_realType (res));
1916 return (res);
1919 static bool
1920 ctbase_isFunction (ctbase c)
1922 llassertfatal (c != ctbase_undefined);
1924 if (c->type == CT_FCN)
1926 return TRUE;
1929 if (c->type == CT_PTR)
1931 ctbase fcn;
1933 fcn = ctype_getCtbase (ctbase_baseArrayPtr (c));
1934 if (ctbase_isDefined (fcn))
1936 if (ctbase_isUA (fcn))
1938 return ctbase_isFunction (ctbase_realType (fcn));
1940 return fcn->type == CT_FCN;
1944 return FALSE;
1947 /* doesn't copy c1 and c2 */
1949 static /*@only@*/ ctbase
1950 ctbase_makeConj (ctype c1, ctype c2, bool isExplicit)
1952 ctbase c = ctbase_new ();
1954 c->type = CT_CONJ;
1956 c->contents.conj = (tconj) dmalloc (sizeof (*c->contents.conj));
1957 c->contents.conj->a = c1;
1958 c->contents.conj->b = c2;
1959 c->contents.conj->isExplicit = isExplicit;
1961 return (c);
1964 static bool ctbase_isAnytype (/*@notnull@*/ ctbase b)
1967 ** A unknown|dne conj is a special representation for an anytype.
1970 if (b->type == CT_CONJ)
1972 /*@access ctype@*/
1973 return (b->contents.conj->a == ctype_unknown
1974 && b->contents.conj->b == ctype_dne);
1975 /*@noaccess ctype@*/
1978 return FALSE;
1981 static ctype
1982 ctbase_getConjA (/*@notnull@*/ ctbase c)
1984 llassert (c->type == CT_CONJ);
1985 return (c->contents.conj->a);
1988 static ctype
1989 ctbase_getConjB (/*@notnull@*/ ctbase c)
1991 llassert (c->type == CT_CONJ);
1992 return (c->contents.conj->b);
1995 static bool
1996 ctbase_isExplicitConj (/*@notnull@*/ ctbase c)
1998 llassert (c->type == CT_CONJ);
1999 return (c->contents.conj->isExplicit);
2002 static /*@only@*/ ctbase
2003 ctbase_createStruct (/*@only@*/ cstring n, /*@only@*/ uentryList f)
2005 ctbase c = ctbase_new ();
2007 c->type = CT_STRUCT;
2009 c->contents.su = (tsu) dmalloc (sizeof (*c->contents.su));
2010 c->contents.su->name = n;
2011 c->contents.su->fields = f;
2013 return (c);
2016 static /*@observer@*/ uentryList
2017 ctbase_getuentryList (/*@notnull@*/ ctbase c)
2019 c = ctbase_realType (c);
2021 if (!(c->type == CT_STRUCT || c->type == CT_UNION))
2022 llfatalbug (message ("ctbase_getuentryList: bad invocation: %q", ctbase_unparse (c)));
2024 return (c->contents.su->fields);
2027 static ctbase
2028 ctbase_createUnion (/*@keep@*/ cstring n, /*@only@*/ uentryList f)
2030 ctbase c = ctbase_new ();
2032 c->type = CT_UNION;
2034 c->contents.su = (tsu) dmalloc (sizeof (*c->contents.su));
2035 c->contents.su->name = n;
2036 c->contents.su->fields = f;
2038 return (c);
2041 static ctype
2042 ctbase_baseArrayPtr (/*@notnull@*/ ctbase c)
2044 ctuid ct;
2045 c = ctbase_realType (c);
2046 ct = c->type;
2048 if (ct == CT_FIXEDARRAY)
2050 return c->contents.farray->base;
2052 else
2054 llassert (ctuid_isAP (ct));
2056 return c->contents.base;
2060 static ctype
2061 ctbase_baseFunction (/*@notnull@*/ ctbase c)
2063 ctbase_fixUser (c);
2064 c = ctbase_realFunction (c);
2066 if (c->type != CT_FCN)
2068 llfatalbug (message ("ctbase_baseFunction: bad call: %q", ctbase_unparse (c)));
2071 return (c->contents.fcn->rval);
2074 static uentryList
2075 ctbase_argsFunction (/*@notnull@*/ ctbase c)
2077 ctbase_fixUser (c);
2078 c = ctbase_realFunction (c);
2080 if (c->type != CT_FCN)
2082 llfatalbug (message ("ctbase_argsFunction: bad call: %q",
2083 ctbase_unparse (c)));
2085 return (c->contents.fcn->params);
2088 static bool
2089 ctbase_baseisExpFcn (ctype c)
2091 ctbase cb;
2092 c = ctype_removePointers (c);
2094 cb = ctype_getCtbase (c);
2095 llassertfatal (ctbase_isDefined (cb));
2097 if (cb->type == CT_FCN)
2099 c = ctype_removePointers (ctype_getReturnType (c));
2101 cb = ctype_getCtbase (c);
2102 llassertfatal (ctbase_isDefined (cb));
2104 return (cb->type == CT_EXPFCN);
2106 return FALSE;
2110 ** ctbase_newBase behaves specially when p is a CONJ:
2112 ** c -> conj (newBase (c, p.a), p.b)
2115 static ctype
2116 ctbase_newBase (ctype c, ctype p)
2118 ctbase cb;
2120 DPRINTF (("New base: %s / %s", ctype_unparse (c), ctype_unparse (p)));
2122 if (ctype_isUndefined (c) || ctype_isUnknown (c))
2124 return p;
2127 cb = ctype_getCtbase (c);
2129 if (ctype_isConj (p))
2131 ctbase pb = ctype_getCtbase (p);
2133 llassertfatal (ctbase_isDefined (pb));
2135 if (pb->contents.conj->isExplicit)
2137 return (ctype_makeExplicitConj (ctype_newBase (c, pb->contents.conj->a),
2138 pb->contents.conj->b));
2141 else
2143 return (ctype_makeConj (ctype_newBase (c, pb->contents.conj->a),
2144 pb->contents.conj->b));
2149 if (ctbase_baseisExpFcn (c))
2151 return (ctbase_newBaseExpFcn (c, p));
2154 llassertfatal (ctbase_isDefined (cb));
2156 switch (cb->type)
2158 case CT_UNKNOWN:
2159 case CT_PRIM:
2160 case CT_USER:
2161 case CT_ENUM:
2162 case CT_ABST:
2163 case CT_NUMABST:
2164 case CT_STRUCT:
2165 case CT_UNION:
2166 case CT_EXPFCN:
2167 return (p);
2169 case CT_PTR:
2171 ctype ret;
2172 ctype cbn;
2174 cbn = ctbase_newBase (cb->contents.base, p);
2175 ret = ctype_makePointer (cbn);
2177 return ret;
2179 case CT_FIXEDARRAY:
2180 return (ctype_makeFixedArray (ctbase_newBase (cb->contents.farray->base, p),
2181 cb->contents.farray->size));
2182 case CT_ARRAY:
2183 return (ctype_makeArray (ctbase_newBase (cb->contents.base, p)));
2184 case CT_FCN:
2185 return (ctype_makeRawFunction (ctbase_newBase (cb->contents.fcn->rval, p),
2186 uentryList_copy (cb->contents.fcn->params)));
2187 case CT_CONJ:
2188 return (ctype_makeConjAux (ctbase_newBase (cb->contents.conj->a, p),
2189 ctbase_newBase (cb->contents.conj->b, p),
2190 cb->contents.conj->isExplicit));
2191 default:
2192 llcontbug (message ("ctbase_newBase: bad ctbase: %q", ctbase_unparse (cb)));
2193 return (p);
2195 BADEXIT;
2198 static ctype
2199 ctbase_newBaseExpFcn (ctype c, ctype p)
2201 ctbase cb = ctype_getCtbase (c);
2202 ctbase tcb;
2203 ctype ret, tmpct;
2204 ctype fp = ctype_unknown;
2205 uentryList ctargs = ctype_argsFunction (c);
2208 ** okay, this is really ugly...
2210 ** pointers inside <expf> mean pointers to the function;
2211 ** pointers outside <expf> are pointers to the return value;
2212 ** because its a function there is one superfluous pointer.
2216 ** bf is a ctype, used to derived structure of cb
2219 if (!ctbase_isFunction (cb))
2220 llbuglit ("ctbase_newBaseExpFcn: expFcn -> not a function");
2222 tmpct = ctype_getBaseType (ctype_getReturnType (c));
2225 ** pointers before expfcn -> p are pointers to function, not result
2229 tcb = ctype_getCtbase (tmpct);
2231 llassertfatal (ctbase_isDefined (tcb));
2232 tmpct = tcb->contents.base;
2235 ** record pointers to base in fp
2238 while (!ctype_isUnknown (tmpct))
2240 if (ctype_isExpFcn (tmpct)) {
2241 ctbase ttcb = ctype_getCtbase (tmpct);
2244 ** evs 2000-05-16: This is necessary to deal with function pointers in parens.
2245 ** The whole function pointer parsing is a major kludge, but it seems to work,
2246 ** and I'm only embarrassed by it when I haven't look at the C spec recently...
2249 llassertfatal (ctbase_isDefined (ttcb));
2250 tmpct = ttcb->contents.base;
2251 llassert (!ctype_isUnknown (tmpct));
2254 switch (ctype_getCtKind (tmpct))
2256 case CTK_PTR:
2257 fp = ctype_makePointer (fp);
2258 /*@switchbreak@*/ break;
2259 case CTK_ARRAY:
2260 fp = ctype_makeArray (fp);
2261 /*@switchbreak@*/ break;
2262 case CTK_COMPLEX:
2264 ctbase fbase = ctype_getCtbase (tmpct);
2266 if (ctbase_isFunction (fbase))
2268 fp = ctype_makeFunction (fp, uentryList_copy (ctargs));
2269 ctargs = ctbase_argsFunction (fbase);
2271 else
2273 llbug
2274 (message
2275 ("ctbase_newBaseExpFcn: fixing expfunction: bad complex type: %s [base: %q]",
2276 ctype_unparse (tmpct), ctbase_unparse (fbase)));
2278 goto exitLoop;
2280 default:
2282 llcontbug
2283 (message ("ctbase_newBaseExpFcn: fixing expfunction: bad type: %s",
2284 ctype_unparse (tmpct)));
2285 goto exitLoop;
2288 tmpct = ctype_baseArrayPtr (tmpct);
2291 exitLoop:
2292 tmpct = ctype_getReturnType (c);
2295 ** pointers to expf are pointers to return value
2298 while (!ctype_isExpFcn (tmpct))
2300 switch (ctype_getCtKind (tmpct))
2302 case CTK_PTR:
2303 p = ctype_makePointer (p);
2304 /*@switchbreak@*/ break;
2305 case CTK_ARRAY:
2306 p = ctype_makeArray (p);
2307 /*@switchbreak@*/ break;
2308 case CTK_COMPLEX:
2310 ctbase fbase = ctype_getCtbase (tmpct);
2312 if (ctbase_isFunction (fbase))
2314 p = ctype_makeFunction (p, uentryList_copy (ctbase_argsFunction (fbase)));
2316 else
2318 llbug
2319 (message
2320 ("ctbase_newBaseExpFcn: fixing expfunction: bad complex type: %s",
2321 ctype_unparse (tmpct)));
2323 goto exitLoop2;
2326 default:
2328 llcontbug
2329 (message ("ctbase_newBaseExpFcn: fixing expfunction2: bad type: %t",
2330 tmpct));
2331 goto exitLoop2;
2334 tmpct = ctype_baseArrayPtr (tmpct);
2337 exitLoop2:
2340 ** pointers to fp are pointers to function type
2343 ret = ctype_makeRawFunction (p, uentryList_copy (ctargs));
2345 while (ctype_getCtKind (fp) > CTK_PLAIN)
2347 switch (ctype_getCtKind (fp))
2349 case CTK_PTR:
2350 ret = ctype_makePointer (ret);
2351 /*@switchbreak@*/ break;
2352 case CTK_ARRAY:
2353 ret = ctype_makeArray (ret);
2354 /*@switchbreak@*/ break;
2355 case CTK_COMPLEX:
2357 ctbase fbase = ctype_getCtbase (fp);
2359 if (ctbase_isFunction (fbase))
2361 ret =
2362 ctype_makeFunction (ret,
2363 uentryList_copy (ctbase_argsFunction (fbase)));
2365 else
2367 BADBRANCH;
2369 goto exitLoop3;
2372 default:
2374 llcontbug (message ("post-fixing expfunction: bad type: %t", fp));
2375 goto exitLoop3;
2378 fp = ctype_baseArrayPtr (fp);
2381 exitLoop3:
2382 return (ret);
2385 #ifdef DEADCODE
2387 ** returns lowest level base of c: plain type
2390 static /*@notnull@*/ /*@only@*/ ctbase
2391 ctbase_getBaseType (/*@notnull@*/ ctbase c)
2393 switch (c->type)
2395 case CT_UNKNOWN:
2396 case CT_PRIM:
2397 case CT_USER:
2398 case CT_ENUM:
2399 case CT_ENUMLIST:
2400 case CT_BOOL:
2401 case CT_ABST:
2402 case CT_NUMABST:
2403 case CT_FCN:
2404 case CT_STRUCT:
2405 case CT_UNION:
2406 return (ctbase_copy (c));
2408 case CT_PTR:
2409 case CT_ARRAY:
2410 return (ctbase_getBaseType (ctype_getCtbaseSafe (c->contents.base)));
2412 case CT_FIXEDARRAY:
2413 return (ctbase_getBaseType (ctype_getCtbaseSafe (c->contents.farray->base)));
2414 case CT_CONJ: /* base type of A conj branch? */
2415 return (ctbase_getBaseType (ctype_getCtbaseSafe (c->contents.conj->a)));
2416 case CT_EXPFCN:
2417 return (ctbase_copy (c));
2419 default:
2420 llfatalbug (message ("ctbase_getBaseType: bad ctbase: %q", ctbase_unparse (c)));
2423 BADEXIT;
2425 #endif
2427 static int
2428 ctbase_compare (ctbase c1, ctbase c2, bool strict)
2430 ctuid c1tid, c2tid;
2432 if (ctbase_isUndefined (c1) || ctbase_isUndefined (c2))
2434 llcontbuglit ("ctbase_compare: undefined ctbase");
2435 return -1;
2438 c1tid = c1->type;
2439 c2tid = c2->type;
2441 if (c1tid < c2tid)
2442 return -1;
2443 if (c1tid > c2tid)
2444 return 1;
2446 switch (c1tid)
2448 case CT_UNKNOWN:
2449 return 0;
2450 case CT_PRIM:
2451 return (int_compare (c1->contents.prim, c2->contents.prim));
2452 case CT_BOOL:
2453 return 0;
2454 case CT_USER:
2455 return (typeId_compare (c1->contents.tid, c2->contents.tid));
2456 case CT_ENUMLIST:
2457 return 1;
2458 case CT_ENUM: /* for now, keep like abstract */
2459 case CT_ABST:
2460 case CT_NUMABST:
2461 return (typeId_compare (c1->contents.tid, c2->contents.tid));
2462 case CT_PTR:
2463 return (ctype_compare (c1->contents.base, c2->contents.base));
2464 case CT_FIXEDARRAY:
2465 INTCOMPARERETURN (c1->contents.farray->size, c2->contents.farray->size);
2467 return (ctype_compare (c1->contents.farray->base,
2468 c2->contents.farray->base));
2469 case CT_ARRAY:
2470 return (ctype_compare (c1->contents.base, c2->contents.base));
2471 case CT_FCN:
2473 COMPARERETURN (ctype_compare (c1->contents.fcn->rval, c2->contents.fcn->rval));
2475 if (strict)
2477 return (uentryList_compareStrict (c1->contents.fcn->params,
2478 c2->contents.fcn->params));
2480 else
2482 return (uentryList_compareParams (c1->contents.fcn->params,
2483 c2->contents.fcn->params));
2486 case CT_EXPFCN:
2487 return (ctype_compare (c1->contents.base, c2->contents.base));
2488 case CT_STRUCT:
2489 case CT_UNION:
2490 /* evs 2000-07-28: this block was missing! */
2491 if (strict) {
2492 int ncmp = cstring_compare (c1->contents.su->name,
2493 c2->contents.su->name);
2495 if (ncmp != 0) {
2496 if (isFakeTag (c1->contents.su->name)
2497 && isFakeTag (c2->contents.su->name)) {
2498 ; /* If they are both fake struct tags, don't require match. */
2499 } else {
2500 return ncmp;
2505 DPRINTF (("Comparing fields: %s / %s",
2506 ctbase_unparse (c1),
2507 ctbase_unparse (c2)));
2509 return (uentryList_compareFields (c1->contents.su->fields,
2510 c2->contents.su->fields));
2511 case CT_CONJ:
2513 COMPARERETURN (ctype_compare (c1->contents.conj->a,
2514 c2->contents.conj->a));
2515 COMPARERETURN (ctype_compare (c1->contents.conj->b,
2516 c2->contents.conj->b));
2517 return (bool_compare (c1->contents.conj->isExplicit,
2518 c2->contents.conj->isExplicit));
2521 BADEXIT;
2524 static int
2525 ctbase_compareStrict (/*@notnull@*/ ctbase c1, /*@notnull@*/ ctbase c2)
2527 return (ctbase_compare (c1, c2, TRUE));
2530 static bool ctbase_equivStrict (/*@notnull@*/ ctbase c1, /*@notnull@*/ ctbase c2)
2532 return (ctbase_compareStrict (c1,c2) == 0);
2535 static bool ctbase_equiv (/*@notnull@*/ ctbase c1, /*@notnull@*/ ctbase c2)
2537 return (ctbase_compare (c1, c2, FALSE) == 0);
2540 static bool
2541 ctbase_isKind (/*@notnull@*/ ctbase c, ctuid kind)
2543 ctuid ck = c->type;
2545 if (ck == kind)
2546 return TRUE;
2548 if (ck == CT_CONJ)
2549 return (ctbase_isKind (ctype_getCtbaseSafe (c->contents.conj->a), kind) ||
2550 ctbase_isKind (ctype_getCtbaseSafe (c->contents.conj->b), kind));
2552 return FALSE;
2555 #ifdef DEADCODE
2556 static bool
2557 ctbase_isKind2 (/*@notnull@*/ ctbase c, ctuid kind1, ctuid kind2)
2559 ctuid ck = c->type;
2561 if (ck == kind1 || ck == kind2)
2562 return TRUE;
2564 if (ck == CT_CONJ)
2565 return (ctbase_isKind2 (ctype_getCtbaseSafe (c->contents.conj->a), kind1, kind2) ||
2566 ctbase_isKind2 (ctype_getCtbaseSafe (c->contents.conj->b), kind1, kind2));
2568 return FALSE;
2570 #endif
2572 static bool
2573 ctbase_isAbstract (/*@notnull@*/ ctbase c)
2575 return (c->type == CT_ABST || c->type == CT_NUMABST);
2578 static bool
2579 ctbase_isNumAbstract (/*@notnull@*/ ctbase c)
2581 return (c->type == CT_NUMABST);
2584 static bool ctbase_isUA (ctbase c)
2586 return (ctbase_isDefined (c) && (ctuid_isAnyUserType (c->type)));
2589 static bool
2590 ctbase_almostEqual (ctbase c1, ctbase c2)
2592 ctuid c1tid, c2tid;
2594 /* undefined types never match */
2596 if (ctbase_isUndefined (c1) || ctbase_isUndefined (c2))
2597 return FALSE;
2599 c1tid = c1->type;
2600 c2tid = c2->type;
2602 if (c1tid == CT_FIXEDARRAY && c2tid == CT_ARRAY)
2604 return (ctbase_almostEqual (ctype_getCtbase (c1->contents.farray->base),
2605 ctype_getCtbase (c2->contents.base)));
2608 if (c2tid == CT_FIXEDARRAY && c1tid == CT_ARRAY)
2610 return (ctbase_almostEqual (ctype_getCtbase (c1->contents.base),
2611 ctype_getCtbase (c2->contents.farray->base)));
2614 if (c1tid != c2tid)
2615 return FALSE;
2617 switch (c1tid)
2619 case CT_UNKNOWN:
2620 return TRUE;
2621 case CT_PRIM:
2622 return (cprim_equal (c1->contents.prim, c2->contents.prim));
2623 case CT_BOOL:
2624 return TRUE;
2625 case CT_ABST:
2626 case CT_NUMABST:
2627 case CT_USER:
2628 return (typeId_equal (c1->contents.tid, c2->contents.tid));
2629 case CT_ENUM:
2630 return (cstring_equal (c1->contents.cenum->tag, c2->contents.cenum->tag));
2631 case CT_PTR:
2632 return (ctype_almostEqual (c1->contents.base, c2->contents.base));
2633 case CT_FIXEDARRAY:
2634 return (ctype_almostEqual (c1->contents.farray->base,
2635 c2->contents.farray->base));
2636 case CT_ARRAY:
2637 return (ctype_almostEqual (c1->contents.base, c2->contents.base));
2638 case CT_FCN:
2639 return (ctype_almostEqual (c1->contents.fcn->rval, c2->contents.fcn->rval)
2640 && uentryList_matchParams (c1->contents.fcn->params,
2641 c2->contents.fcn->params, FALSE, TRUE));
2642 case CT_STRUCT:
2643 case CT_UNION:
2644 if (!cstring_isEmpty (c1->contents.su->name))
2646 return (cstring_equal (c1->contents.su->name, c2->contents.su->name));
2648 else
2650 if (!cstring_isEmpty (c2->contents.su->name))
2652 return FALSE;
2655 llcontbuglit ("ctbase_almostEqual: match fields");
2656 return (FALSE);
2658 default:
2659 llcontbug (message ("ctbase_almostEqual: unknown type: %d\n", (int)c1tid));
2660 return (FALSE);
2664 /*drl added July 02, 001
2665 called by ctype_getArraySize
2668 static size_t ctbase_getArraySize (ctbase ctb)
2670 /*drl 1/25/2002 fixed discovered by Jim Francis */
2671 ctbase r;
2673 llassert (ctbase_isDefined (ctb));
2674 r = ctbase_realType (ctb);
2675 llassert (ctbase_isFixedArray(r));
2677 return (r->contents.farray->size);
2680 static bool ctbase_isBigger (ctbase ct1, ctbase ct2)
2682 if (ct1 != NULL && ct2 != NULL
2683 && (ct1->type == CT_PRIM && ct2->type == CT_PRIM))
2685 /* Only compare sizes for primitives */
2686 cprim cp1 = ct1->contents.prim;
2687 cprim cp2 = ct2->contents.prim;
2688 int nbits1 = cprim_getExpectedBits (cp1);
2689 int nbits2 = cprim_getExpectedBits (cp2);
2691 if (nbits1 > nbits2) {
2692 return TRUE;
2693 } else {
2694 return FALSE;
2697 else
2699 return FALSE;
2703 static int ctbase_getSize (ctbase ct)
2705 if (ct == NULL)
2707 return 0;
2710 switch (ct->type)
2712 case CT_UNKNOWN:
2713 case CT_BOOL:
2714 case CT_PRIM:
2716 cprim cp = ct->contents.prim;
2717 int nbits = cprim_getExpectedBits (cp);
2718 return nbits;
2720 case CT_USER:
2721 case CT_ABST:
2722 case CT_NUMABST:
2723 case CT_EXPFCN:
2725 return 0;
2727 case CT_PTR:
2729 /* Malloc returns void *, but they are bytes. Normal void * is pointer size. */
2730 if (ctype_isVoid (ct->contents.base))
2732 return 8;
2734 else
2736 return ctype_getSize (ct->contents.base);
2739 case CT_FIXEDARRAY:
2740 case CT_ARRAY:
2741 case CT_FCN:
2742 case CT_STRUCT:
2743 case CT_UNION:
2744 case CT_ENUM:
2745 case CT_CONJ:
2746 break;
2747 BADDEFAULT;
2750 return 0;