2 ** Copyright (c) Massachusetts Institute of Technology 1994-1998.
3 ** All Rights Reserved.
4 ** Unpublished rights reserved under the copyright laws of
7 ** THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
8 ** OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
10 ** This code is distributed freely and may be used freely under the
11 ** following conditions:
13 ** 1. This notice may not be removed or altered.
15 ** 2. Works derived from this code are not distributed for
16 ** commercial gain without explicit permission from MIT
17 ** (for permission contact lclint-request@sds.lcs.mit.edu).
22 ** NOTE: This is not a stand-alone source file, but is included in ctype.c.
23 ** (This is necessary becuase there is no other way in C to have a
24 ** hidden scope, besides at the file level.)
29 typedef /*@null@*/ struct __ctbase *ctbase;
31 typedef struct _ctentry {
34 ctype base; /* type I point to (or element of array) */
35 ctype ptr; /* type of pointer to me */
36 ctype array; /* type of array of me */
37 cstring unparse; /* unparse me, if memoized */
40 typedef /*@only@*/ ctentry o_ctentry;
42 typedef struct _cttable {
45 /*@relnull@*/ /*@only@*/ o_ctentry *entries;
46 /* memoize matches...maybe in context? */
49 extern bool ctentry_isBogus (/*@sef@*/ ctentry p_c) /*@*/;
50 # define ctentry_isBogus(c) \
51 ((c)->kind == CTK_INVALID || (c)->kind == CTK_DNE)
53 static cttable cttab = { 0, 0, NULL };
55 static /*@notnull@*/ /*@only@*/ ctbase ctbase_createAbstract (typeId p_u);
56 static /*@observer@*/ cstring ctentry_doUnparse (ctentry p_c) /*@modifies p_c@*/;
57 static /*@only@*/ ctentry
58 ctentry_make (ctkind p_ctk, /*@keep@*/ ctbase p_c, ctype p_base,
59 ctype p_ptr, ctype p_array, /*@keep@*/ cstring p_unparse);
60 static /*@only@*/ ctentry ctentry_makeNew (ctkind p_ctk, /*@only@*/ ctbase p_c);
61 static /*@only@*/ cstring ctentry_unparse (ctentry p_c) /*@*/ ;
63 static void cttable_grow (void);
64 static ctype cttable_addDerived (ctkind p_ctk, /*@keep@*/ ctbase p_cnew, ctype p_base);
65 static ctype cttable_addFull (/*@keep@*/ ctentry p_cnew);
66 static bool ctentry_isInteresting (ctentry p_c) /*@*/;
67 static /*@notnull@*/ /*@only@*/ ctbase ctbase_makeFixedArray (ctype p_b, long p_size) /*@*/ ;
70 ** These are file-static macros (used in ctype.c). No way to
71 ** declare them as static in C.
74 /*@-allmacros@*/ /*@-macrospec@*/ /*@-namechecks@*/
75 # define ctentry_getBase(c) ((c)->base)
76 # define ctentry_getKind(c) ((c)->kind)
77 # define ctentry_getArray(c) ((c)->array)
78 # define ctentry_getPtr(c) ((c)->ptr)
79 # define ctentry_isArray(c) ((c)->kind == CTK_ARRAY)
80 # define ctentry_isComplex(c) ((c)->kind == CTK_COMPLEX)
81 # define ctentry_isPlain(c) ((c)->kind == CTK_PLAIN)
82 # define ctentry_isPointer(c) ((c)->kind == CTK_PTR)
83 # define ctentry_setArray(c,b) ((c)->array = (b))
84 # define ctentry_setPtr(c,b) ((c)->ptr = (b))
86 # define ctbase_fixUser(c) (c = ctbase_realType(c))
87 /*@=allmacros@*/ /*@=macrospec@*/ /*@=namechecks@*/
89 static ctype cttable_addComplex (/*@notnull@*/ /*@only@*/ ctbase p_cnew);
90 static /*@observer@*/ ctbase ctype_getCtbase (ctype p_c) /*@*/ ;
91 static ctype ctype_makeConjAux (ctype p_c1, ctype p_c2, bool p_isExplicit) /*@*/ ;
92 static /*@notnull@*/ /*@observer@*/ ctbase ctype_getCtbaseSafe (ctype p_c) /*@*/ ;
93 static /*@observer@*/ ctentry ctype_getCtentry (ctype p_c) /*@*/ ;
94 static /*@observer@*/ /*@notnull@*/ ctbase
95 ctbase_realType (/*@notnull@*/ ctbase p_c) /*@*/ ;
96 static bool ctbase_isPointer (/*@notnull@*/ /*@dependent@*/ ctbase p_c) /*@*/ ;
97 static bool ctbase_isEitherArray (/*@notnull@*/ /*@dependent@*/ ctbase p_c) /*@*/ ;
98 static /*@observer@*/ enumNameList ctbase_elist (ctbase p_c) /*@*/ ;
99 static /*@only@*/ cstring ctbase_unparse (ctbase p_c) /*@*/ ;
100 static /*@only@*/ cstring ctbase_unparseDeep (ctbase p_c) /*@*/ ;
101 static /*@only@*/ /*@notnull@*/ ctbase ctbase_copy (/*@notnull@*/ ctbase p_c) /*@*/ ;
102 static void ctbase_free (/*@only@*/ ctbase p_c);
103 static /*@notnull@*/ /*@only@*/ ctbase ctbase_createPrim (cprim p_p) /*@*/ ;
104 static /*@notnull@*/ /*@only@*/ ctbase ctbase_createBool (void) /*@*/ ;
105 static /*@notnull@*/ /*@observer@*/ ctbase ctbase_getBool (void) /*@*/ ;
106 static /*@notnull@*/ /*@only@*/ ctbase ctbase_createUser (typeId p_u) /*@*/ ;
108 static /*@notnull@*/ /*@only@*/ ctbase
109 ctbase_createStruct (/*@only@*/ cstring p_n, /*@only@*/ uentryList p_f);
111 static /*@notnull@*/ /*@only@*/ ctbase
112 ctbase_createUnion (/*@keep@*/ cstring p_n, /*@only@*/ uentryList p_f);
113 static /*@notnull@*/ /*@only@*/ ctbase ctbase_createEnum (/*@keep@*/ cstring p_etag, /*@keep@*/ enumNameList p_emembers);
114 static /*@notnull@*/ /*@only@*/ ctbase ctbase_createUnknown (void);
115 static bool ctbase_match (ctbase p_c1, ctbase p_c2) /*@modifies nothing@*/;
116 static bool ctbase_matchDef (ctbase p_c1, ctbase p_c2) /*@modifies nothing@*/;
117 static bool ctbase_genMatch (ctbase p_c1, ctbase p_c2, bool p_force, bool p_arg, bool p_def);
118 static bool ctbase_isAbstract (/*@notnull@*/ ctbase p_c) /*@*/ ;
119 static /*@notnull@*/ /*@only@*/ ctbase ctbase_makePointer (ctype p_b) /*@*/ ;
120 static /*@notnull@*/ /*@only@*/ ctbase ctbase_makeArray (ctype p_b) /*@*/ ;
121 static /*@notnull@*/ ctype
122 ctbase_makeFunction (ctype p_b, /*@only@*/ uentryList p_p) /*@*/ ;
123 static /*@notnull@*/ /*@only@*/ ctbase
124 ctbase_makeRealFunction (ctype p_b, /*@dependent@*/ uentryList p_p) /*@*/ ;
125 static /*@notnull@*/ /*@observer@*/ ctbase
126 ctbase_realFunction (/*@notnull@*/ /*@dependent@*/ ctbase p_c) /*@*/ ;
127 static ctype ctbase_baseArrayPtr (/*@notnull@*/ ctbase p_c) /*@*/ ;
128 static ctype ctbase_baseFunction (/*@notnull@*/ ctbase p_c) /*@*/ ;
129 static /*@observer@*/ uentryList ctbase_argsFunction (/*@notnull@*/ ctbase p_c) /*@*/ ;
130 static /*@observer@*/ uentryList ctbase_getuentryList (/*@notnull@*/ ctbase p_c) /*@*/ ;
131 static ctype ctbase_newBase (ctype p_c, ctype p_p) /*@*/ ;
132 static ctype ctbase_newBaseExpFcn (ctype p_c, ctype p_p) /*@*/ ;
133 static bool ctbase_isFixedArray (/*@notnull@*/ ctbase p_c) /*@*/ ;
136 extern int cttable_lastIndex();
137 # define cttable_lastIndex() (cttab.size - 1)
143 /*@dependent@*/ uentryList params; /* params are owned if liveparams is TRUE */
153 typedef struct _tconj
160 typedef struct _tenum
163 enumNameList members;
166 typedef struct _tfixed
172 typedef union _uconts
174 cprim prim; /* primitive */
175 typeId tid; /* abstract, user */
176 ctype base; /* ptr, array */
177 cfcn fcn; /* function */
178 tsu su; /* struct union */
179 tenum cenum; /* enum */
180 tconj conj; /* conj */
181 tfixed farray; /* fixed array */
190 static /*@falsenull@*/ bool ctbase_isUA (ctbase p_c) /*@*/ ;
191 static bool ctbase_isBaseUA(ctbase p_c) /*@*/ ;
192 static typeId ctbase_typeBaseUid(ctbase p_c) /*@*/ ;
193 static bool ctbase_isKind (/*@notnull@*/ ctbase p_c, ctuid p_kind) /*@*/ ;
194 static bool ctbase_isKind2 (/*@notnull@*/ ctbase p_c, ctuid p_kind1, ctuid p_kind2) /*@*/ ;
195 static /*@only@*/ /*@notnull@*/ ctbase
196 ctbase_getBaseType (/*@notnull@*/ ctbase p_c) /*@*/ ;
198 static /*@falsenull@*/ bool ctbase_isFunction(ctbase p_c) /*@*/ ;
200 /*@constant null ctbase ctbase_undefined; @*/
201 # define ctbase_undefined ((ctbase)0)
203 static /*@owned@*/ ctbase ctbase_bool = ctbase_undefined;
204 static /*@owned@*/ ctbase ctbase_unknown = ctbase_undefined;
206 static /*@falsenull@*/ bool ctbase_isDefined (ctbase c) /*@*/
208 return ((c) != ctbase_undefined);
211 static /*@truenull@*/ bool ctbase_isUndefined (ctbase c)
213 return ((c) == ctbase_undefined);
216 static ctkind ctype_getCtKind (ctype c)
218 ctentry ce = ctype_getCtentry (c);
220 return ctentry_getKind (ce);
223 static bool ctbase_isUser (ctbase c)
225 if (ctbase_isDefined (c))
227 return (ctbase_isKind (c, CT_USER));
235 static bool ctbase_isEnum (ctbase c)
237 if (ctbase_isDefined (c))
239 return (ctbase_isKind (c, CT_ENUM));
247 static bool ctbase_isExpFcn (ctbase c)
249 if (ctbase_isDefined (c))
251 return (c->type == CT_EXPFCN);
259 static /*@falsenull@*/ bool ctbase_isConj (ctbase c)
261 if (ctbase_isDefined (c))
263 return (c->type == CT_CONJ);
271 static bool ctuid_isAP (ctuid c) /*@*/
273 return (c == CT_ARRAY || c == CT_PTR);
276 static typeId ctbase_typeId (ctbase p_c);
277 static /*@only@*/ cstring ctbase_dump (ctbase p_c);
278 static /*@only@*/ ctbase ctbase_undump (char **p_c);
279 static int ctbase_compare (ctbase p_c1, ctbase p_c2, bool p_strict);
280 static bool ctbase_matchArg (ctbase p_c1, ctbase p_c2);
281 static /*@notnull@*/ /*@only@*/ ctbase
282 ctbase_makeConj (ctype p_c1, ctype p_c2, bool p_isExplicit) /*@*/ ;
283 static ctype ctbase_getConjA (/*@notnull@*/ ctbase p_c) /*@*/ ;
284 static ctype ctbase_getConjB (/*@notnull@*/ ctbase p_c) /*@*/ ;
285 static bool ctbase_isExplicitConj (/*@notnull@*/ ctbase p_c) /*@*/ ;
286 static bool ctbase_forceMatch (ctbase p_c1, ctbase p_c2);
287 static /*@notnull@*/ /*@only@*/ ctbase ctbase_expectFunction (ctype p_c);
288 static bool ctbase_isVoidPointer(/*@notnull@*/ /*@dependent@*/ ctbase p_c) /*@*/ ;
289 static bool ctbase_isUnion (/*@notnull@*/ /*@dependent@*/ ctbase p_c) /*@*/ ;
290 static bool ctbase_isStruct (/*@notnull@*/ /*@dependent@*/ ctbase p_c) /*@*/ ;
291 static /*@observer@*/ cstring ctbase_enumTag (/*@notnull@*/ ctbase p_ct) /*@*/ ;
292 static /*@only@*/ cstring ctbase_unparseNotypes (ctbase p_c) /*@*/ ;
294 static /*@out@*/ /*@notnull@*/ /*@only@*/ ctbase ctbase_new (void) /*@*/ ;
295 static int nctbases = 0;
297 static /*@notnull@*/ /*@only@*/
298 ctbase ctbase_makeLiveFunction (ctype p_b, /*@owned@*/ uentryList p_p);
300 static /*@observer@*/ ctbase ctbase_realType (ctbase c)
304 typeId uid = ctbase_typeId (c);
306 if (usymtab_isBoolType (uid))
308 return ctbase_getBool ();
312 ctbase ret = ctype_getCtbase
313 (uentry_getRealType (usymtab_getTypeEntry (ctbase_typeId (c))));
315 llassert (ret != ctbase_undefined);
326 ctbase_isVoidPointer (/*@dependent@*/ /*@notnull@*/ ctbase c)
328 ctbase r = ctbase_realType (c);
330 return (ctbase_isKind (r, CT_PTR) &&
331 ctype_isVoid (r->contents.base));
335 ctbase_isPointer (/*@notnull@*/ /*@dependent@*/ ctbase c)
337 ctbase r = ctbase_realType (c);
339 return (ctbase_isKind (r, CT_PTR));
343 ctbase_isEitherArray (/*@notnull@*/ ctbase c)
345 ctbase r = ctbase_realType (c);
347 return (ctbase_isKind (r, CT_ARRAY)
348 || ctbase_isKind (r, CT_FIXEDARRAY));
352 ctbase_isFixedArray (/*@notnull@*/ ctbase c)
354 ctbase r = ctbase_realType (c);
356 return (ctbase_isKind (r, CT_FIXEDARRAY));
360 ctbase_isStruct (/*@notnull@*/ ctbase c)
362 ctbase r = ctbase_realType (c);
364 return (ctbase_isKind (r, CT_STRUCT));
368 ctbase_isUnion (/*@notnull@*/ /*@dependent@*/ ctbase c)
370 ctbase r = ctbase_realType (c);
372 return (ctbase_isKind (r, CT_UNION));
376 ** clean this up -> typeTable should store ctype
380 ctbase_typeBaseUid (ctbase c)
384 if (ctbase_isDefined (c))
390 return ctbase_typeBaseUid (ctype_getCtbase (c->contents.base));
392 else if (ct == CT_USER || ct == CT_ABST)
394 return c->contents.tid;
396 else if (ct == CT_FIXEDARRAY)
398 return ctbase_typeBaseUid (ctype_getCtbase (c->contents.farray->base));
402 llcontbuglit ("ctbase_typeBaseUid: bad call");
403 return typeId_invalid;
406 return typeId_invalid;
410 ctbase_isBaseUA (ctbase c)
414 if (ctbase_isDefined (c))
420 return ctbase_isBaseUA (ctype_getCtbase (c->contents.base));
422 else if (ct == CT_FIXEDARRAY)
424 return ctbase_isBaseUA (ctype_getCtbase (c->contents.farray->base));
427 return (ct == CT_USER || ct == CT_ABST);
433 ctbase_typeId (ctbase c)
437 return c->contents.tid;
441 llcontbug (message ("ctbase_typeId: bad call: %q", ctbase_unparse (c)));
442 return typeId_invalid;
446 static /*@only@*/ cstring
447 ctbase_unparse (ctbase c)
449 if (ctbase_isUndefined (c)) {
450 return cstring_makeLiteral ("<<undef>>");
456 return cstring_makeLiteral ("?");
458 return cstring_copy (context_printBoolName ());
460 return (cprim_unparse (c->contents.prim));
462 return (usymtab_getTypeEntryName (c->contents.tid));
464 return (usymtab_getTypeEntryName (c->contents.tid));
466 return (message ("<expf: %t>", c->contents.base));
468 /* no spaces for multiple pointers */
470 if (ctype_isPointer (c->contents.base))
472 return (cstring_appendChar (cstring_copy (ctype_unparse (c->contents.base)), '*'));
476 return (message ("%t *", c->contents.base));
479 return (message ("%t [%d]", c->contents.farray->base,
480 (int) c->contents.farray->size));
482 return (message ("%t []", c->contents.base));
484 return (message ("[function (%q) returns %t]",
485 uentryList_unparseParams (c->contents.fcn->params),
486 c->contents.fcn->rval));
488 if (cstring_isDefined (c->contents.su->name) &&
489 !cstring_isEmpty (c->contents.su->name) &&
490 !isFakeTag (c->contents.su->name))
492 return (message ("struct %s", c->contents.su->name));
496 return (message ("struct { %q }", uentryList_unparseAbbrev (c->contents.su->fields)));
499 if (cstring_isDefined (c->contents.su->name) &&
500 !cstring_isEmpty (c->contents.su->name) &&
501 !isFakeTag (c->contents.su->name))
503 return (message ("union %s", c->contents.su->name));
507 return (message ("union { %q }",
508 uentryList_unparseAbbrev (c->contents.su->fields)));
511 if (isFakeTag (c->contents.cenum->tag))
513 return (message ("enum { %q }",
514 enumNameList_unparseBrief (c->contents.cenum->members)));
518 return (message ("enum %s { %q }",
519 c->contents.cenum->tag,
520 enumNameList_unparseBrief (c->contents.cenum->members)));
523 if (c->contents.conj->isExplicit || context_getFlag (FLG_SHOWALLCONJS))
525 if (!ctype_isSimple (c->contents.conj->a) ||
526 !ctype_isSimple (c->contents.conj->b))
528 return (message ("<%t> | <%t>", c->contents.conj->a, c->contents.conj->b));
532 return (message ("%t | %t", c->contents.conj->a, c->contents.conj->b));
537 return (cstring_copy (ctype_unparse (c->contents.conj->a)));
544 static /*@only@*/ cstring
545 ctbase_unparseDeep (ctbase c)
547 if (ctbase_isUndefined (c))
549 return cstring_makeLiteral ("<<undef>>");
555 return cstring_makeLiteral ("?");
557 return cstring_copy (context_printBoolName ());
559 return (cprim_unparse (c->contents.prim));
561 if (cstring_isNonEmpty (c->contents.cenum->tag))
563 return (message ("enum %s { %q }",
564 c->contents.cenum->tag,
565 enumNameList_unparse (c->contents.cenum->members)));
569 return (message ("enum { %q }",
570 enumNameList_unparse (c->contents.cenum->members)));
573 return (usymtab_getTypeEntryName (c->contents.tid));
575 return (usymtab_getTypeEntryName (c->contents.tid));
577 return (message ("<expf: %t>", c->contents.base));
579 return (message ("%t *", c->contents.base));
581 return (message ("%t [%d]", c->contents.farray->base,
582 (int) c->contents.farray->size));
584 return (message ("%t []", c->contents.base));
586 return (message ("[function (%q) returns %t]",
587 uentryList_unparse (c->contents.fcn->params),
588 c->contents.fcn->rval));
590 return (message ("struct %s { ... } ", c->contents.su->name));
592 return (message ("union %s { ... }", c->contents.su->name));
594 return (message ("%t", c->contents.conj->a));
600 static /*@only@*/ cstring
601 ctbase_unparseNotypes (ctbase c)
603 llassert (ctbase_isDefined (c));
608 return cstring_makeLiteral ("?");
610 return cstring_copy (context_printBoolName ());
612 return (cprim_unparse (c->contents.prim));
614 if (typeId_isInvalid (c->contents.tid))
616 return cstring_makeLiteral ("enum");
620 return (message ("T#%d", c->contents.tid));
623 return (message ("uT#%d", c->contents.tid));
625 return (message ("aT#%d", c->contents.tid));
627 return (message ("<expf: %q >", ctbase_unparseNotypes (ctype_getCtbase (c->contents.base))));
629 return (message ("%q *", ctbase_unparseNotypes (ctype_getCtbase (c->contents.base))));
631 return (message ("%q []", ctbase_unparseNotypes (ctype_getCtbase (c->contents.base))));
633 return (message ("[function (%d) returns %q]", uentryList_size (c->contents.fcn->params),
634 ctbase_unparseNotypes (ctype_getCtbase (c->contents.fcn->rval))));
636 return (message ("struct %s", c->contents.su->name));
638 return (message ("union %s", c->contents.su->name));
640 return (message ("[enumlist]"));
642 return (message ("%q/%q",
643 ctbase_unparseNotypes (ctype_getCtbase (c->contents.conj->a)),
644 ctbase_unparseNotypes (ctype_getCtbase (c->contents.conj->b))));
650 static /*@only@*/ cstring
651 ctbase_unparseDeclaration (ctbase c, /*@only@*/ cstring name) /*@*/
653 if (ctbase_isUndefined (c))
661 return (message ("? %q", name));
663 return (message ("%s %q", context_printBoolName (), name));
665 return (message ("%q %q", cprim_unparse (c->contents.prim), name));
668 return (message ("%q %q", usymtab_getTypeEntryName (c->contents.tid), name));
670 llcontbuglit ("ctbase_unparseDeclaration: expfcn");
673 if (ctype_isFunction (c->contents.base))
675 return ctbase_unparseDeclaration (ctype_getCtbase (c->contents.base), name);
679 cstring s = cstring_prependChar ('*', name);
680 cstring ret = ctbase_unparseDeclaration (ctype_getCtbase (c->contents.base), s);
685 return (message ("%q[%d]",
686 ctbase_unparseDeclaration (ctype_getCtbase (c->contents.farray->base), name),
687 (int) c->contents.farray->size));
689 return (message ("%q[]",
690 ctbase_unparseDeclaration (ctype_getCtbase (c->contents.base), name)));
693 cstring s = message ("%q(%q)", name,
694 uentryList_unparseParams (c->contents.fcn->params));
696 return (ctbase_unparseDeclaration
697 (ctype_getCtbase (c->contents.fcn->rval), s));
700 if (cstring_isDefined (c->contents.su->name) &&
701 !cstring_isEmpty (c->contents.su->name) &&
702 !isFakeTag (c->contents.su->name))
704 return (message ("struct %s %q", c->contents.su->name, name));
708 return (message ("struct { %q } %q",
709 uentryList_unparseAbbrev (c->contents.su->fields),
713 if (cstring_isDefined (c->contents.su->name) &&
714 !cstring_isEmpty (c->contents.su->name) &&
715 !isFakeTag (c->contents.su->name))
717 return (message ("union %s %q", c->contents.su->name, name));
721 return (message ("union { %q } %q",
722 uentryList_unparseAbbrev (c->contents.su->fields),
726 if (isFakeTag (c->contents.cenum->tag))
728 return (message ("enum { %q } %q",
729 enumNameList_unparseBrief (c->contents.cenum->members),
734 return (message ("enum %s { %q } %q",
735 c->contents.cenum->tag,
736 enumNameList_unparseBrief (c->contents.cenum->members),
740 if (c->contents.conj->isExplicit || context_getFlag (FLG_SHOWALLCONJS))
742 if (!ctype_isSimple (c->contents.conj->a) ||
743 !ctype_isSimple (c->contents.conj->b))
745 cstring name1 = cstring_copy (name);
750 ctbase_unparseDeclaration
751 (ctype_getCtbase (c->contents.conj->a), name1),
752 ctbase_unparseDeclaration
753 (ctype_getCtbase (c->contents.conj->b), name)));
757 cstring s1 = ctbase_unparseDeclaration (ctype_getCtbase (c->contents.conj->a),
758 cstring_copy (name));
760 (message ("%q | %q", s1,
761 ctbase_unparseDeclaration (ctype_getCtbase (c->contents.conj->b),
768 return (cstring_copy (ctype_unparse (c->contents.conj->a)));
775 static ctbase ctbase_undump (d_char *c)
785 return (ctbase_undefined);
787 return (ctbase_createUnknown ());
789 return (ctbase_createBool ());
791 res = ctbase_createPrim (cprim_fromInt (getInt (c)));
795 res = ctbase_createUser (typeId_fromInt (getInt (c)));
799 res = ctbase_createAbstract (typeId_fromInt (getInt (c)));
803 res = ctbase_makePointer (ctype_undump (c));
807 res = ctbase_makeArray (ctype_undump (c));
812 ctype ct = ctype_undump (c);
818 return (ctbase_makeFixedArray (ct, size));
823 char *lp = strchr (*c, '(');
825 llassertfatal (lp != NULL);
828 ct = ctype_undump (c);
831 return (ctbase_makeLiveFunction (ct, uentryList_undump (c)));
838 char *lc = strchr (*c, '{');
840 llassert (lc != NULL);
843 sname = mstring_copy (*c);
851 i = (unsigned) atoi (sname + 1);
856 fields = uentryList_undumpFields (c, g_currentloc);
858 ctb = ctbase_createStruct (cstring_fromCharsO (sname), fields);
864 char *lc = strchr (*c, '{');
866 llassert (lc != NULL);
869 sname = mstring_copy (*c);
870 llassert (sname != NULL);
878 i = (unsigned) atoi (sname + 1);
882 return (ctbase_createUnion (cstring_fromCharsO (sname),
883 uentryList_undumpFields (c, g_currentloc)));
889 char *lc = strchr (*c, '{');
891 llassert (lc != NULL);
894 sname = mstring_copy (*c);
901 i = (unsigned) atoi (sname + 1);
905 ret = ctbase_createEnum (cstring_fromCharsO (sname),
906 enumNameList_undump (c));
914 isExplicit = bool_fromInt (getInt (c));
916 c1 = ctype_undump (c);
918 c2 = ctype_undump (c);
921 return (ctbase_makeConj (c1, c2, isExplicit));
927 message ("Bad Library line (type): %s", cstring_fromChars (*c)));
934 return ctbase_createUnknown ();
938 /* first letter of c encodes type: */
954 static /*@only@*/ cstring
955 ctbase_dump (ctbase c)
957 if (!ctbase_isDefined (c))
959 return cstring_makeLiteral ("?");
965 return cstring_makeLiteral ("u");
967 return cstring_makeLiteral ("b");
969 return (message ("p%d|", c->contents.prim));
971 return (message ("s%d|",
972 usymtab_convertId (c->contents.tid)));
974 return (message ("a%d|", usymtab_convertId (c->contents.tid)));
976 return (message ("t%q|", ctype_dump (c->contents.base)));
978 return (message ("y%q|", ctype_dump (c->contents.base)));
980 return (message ("F%q/%d|",
981 ctype_dump (c->contents.farray->base),
982 (int) c->contents.farray->size));
984 return (message ("f%q (%q)", ctype_dump (c->contents.fcn->rval),
985 uentryList_dumpParams (c->contents.fcn->params)));
987 return (message ("S%s{%q}", c->contents.su->name,
988 uentryList_dumpFields (c->contents.su->fields)));
990 return (message ("U%s{%q}", c->contents.su->name,
991 uentryList_dumpFields (c->contents.su->fields)));
996 if (cstring_isNonEmpty (c->contents.cenum->tag))
998 s = message ("e%s{%q}",
999 c->contents.cenum->tag,
1000 enumNameList_dump (c->contents.cenum->members));
1004 s = message ("e{%q}",
1005 enumNameList_dump (c->contents.cenum->members));
1010 return (message ("C%d.%q/%q|",
1011 bool_toInt (c->contents.conj->isExplicit),
1012 ctype_dump (c->contents.conj->a),
1013 ctype_dump (c->contents.conj->b)));
1015 /* should clean them up! */
1016 return (cstring_makeLiteral ("?"));
1018 llcontbug (message ("Cannot dump: %q", ctbase_unparse (c)));
1019 return (message ("u"));
1026 static /*@only@*/ ctbase
1027 ctbase_copy (/*@notnull@*/ ctbase c)
1032 return (ctbase_createUnknown ());
1034 return (ctbase_createBool ());
1036 return (ctbase_createEnum (cstring_copy (c->contents.cenum->tag),
1037 enumNameList_copy (c->contents.cenum->members)));
1039 return (ctbase_createPrim (c->contents.prim));
1041 return (ctbase_createUser (c->contents.tid));
1043 return (ctbase_createAbstract (c->contents.tid));
1045 return (ctbase_expectFunction (c->contents.base));
1047 return (ctbase_makePointer (c->contents.base));
1049 return (ctbase_makeArray (c->contents.base));
1051 return (ctbase_makeLiveFunction (c->contents.fcn->rval,
1052 uentryList_copy (c->contents.fcn->params)));
1054 return (ctbase_createStruct (cstring_copy (c->contents.su->name),
1055 uentryList_copy (c->contents.su->fields)));
1057 return (ctbase_createUnion (cstring_copy (c->contents.su->name),
1058 uentryList_copy (c->contents.su->fields)));
1060 /*@i@*/ return (c); /* not a real copy for conj's */
1062 llbug (message ("ctbase_copy: %q", ctbase_unparse (c)));
1069 ctbase_elist (ctbase c)
1071 llassert (ctbase_isDefined (c));
1072 llassert (c->type == CT_ENUM);
1074 return (c->contents.cenum->members);
1078 ctbase_free (/*@only@*/ ctbase c)
1080 if (c == ctbase_bool || c == ctbase_unknown)
1082 /*@-mustfree@*/ return; /*@=mustfree@*/
1088 if (ctbase_isDefined (c))
1117 if (c->contents.fcn->liveparams)
1119 /* Because of liveparams, we know this can be released. */
1121 /*@-dependenttrans@*/ /*@-unqualifiedtrans@*/
1122 uentryList_free (c->contents.fcn->params);
1123 c->contents.fcn->params = NULL;
1124 /*@=dependenttrans@*/ /*@=unqualifiedtrans@*/
1131 cstring_free (c->contents.su->name);
1132 uentryList_free (c->contents.su->fields);
1136 /* Don't bree conj's, */
1146 ** c should be * <unknown>
1149 static /*@only@*/ ctbase
1150 ctbase_expectFunction (ctype c)
1152 ctbase f = ctbase_new ();
1154 f->type = CT_EXPFCN;
1155 f->contents.base = c;
1161 ctbase_genMatch (ctbase c1, ctbase c2, bool force, bool arg, bool def)
1165 /* undefined types never match */
1167 if (ctbase_isUndefined (c1) || ctbase_isUndefined (c2))
1170 /* abstract types match user types of same name */
1172 c1 = ctbase_realType (c1);
1173 c2 = ctbase_realType (c2);
1178 if (c1tid == CT_CONJ)
1180 return (ctbase_genMatch (ctype_getCtbase (c1->contents.conj->a), c2,
1182 || ctbase_genMatch (ctype_getCtbase (c1->contents.conj->b), c2,
1186 if (c2tid == CT_CONJ)
1188 return (ctbase_genMatch (c1, ctype_getCtbase (c2->contents.conj->a),
1190 || ctbase_genMatch (c1, ctype_getCtbase (c2->contents.conj->b),
1195 ** if the types don't match, there are some special cases...
1200 /* unknowns match anything */
1202 if (c1tid == CT_UNKNOWN || c2tid == CT_UNKNOWN)
1207 if (c1tid == CT_FIXEDARRAY
1208 && (c2tid == CT_ARRAY || (!def && c2tid == CT_PTR)))
1210 if (ctype_isVoid (c2->contents.base))
1212 return (context_getFlag (FLG_ABSTVOIDP) ||
1213 (!(ctype_isRealAbstract (c1->contents.farray->base)) &&
1214 !(ctype_isRealAbstract (c2->contents.base))));
1217 return (ctbase_genMatch (ctype_getCtbase (c1->contents.farray->base),
1218 ctype_getCtbase (c2->contents.base),
1223 if (c2tid == CT_FIXEDARRAY
1224 && (c1tid == CT_ARRAY || (!def && c1tid == CT_PTR)))
1226 if (ctype_isVoid (c1->contents.base))
1228 return (context_getFlag (FLG_ABSTVOIDP) ||
1229 (!(ctype_isRealAbstract (c2->contents.farray->base)) &&
1230 !(ctype_isRealAbstract (c1->contents.base))));
1233 return (ctbase_genMatch (ctype_getCtbase (c1->contents.base),
1234 ctype_getCtbase (c2->contents.farray->base),
1238 /* in most cases, bool and int are matched if FLG_BOOLINT */
1240 if ((c1tid == CT_BOOL
1241 && (c2tid == CT_PRIM && cprim_isInt (c2->contents.prim))) ||
1243 && (c1tid == CT_PRIM && cprim_isInt (c1->contents.prim))))
1245 return (context_msgBoolInt ());
1248 if ((c1tid == CT_ENUM
1249 && (c2tid == CT_PRIM && cprim_isInt (c2->contents.prim))) ||
1251 && (c1tid == CT_PRIM && cprim_isInt (c1->contents.prim))))
1253 return (context_msgEnumInt ());
1257 ** arrays and pointers...yuk!
1259 ** Considered equivalent except in definitions.
1260 ** (e.g., function parameters are equivalent)
1266 if (ctuid_isAP (c1tid) && ctuid_isAP (c2tid))
1273 ** Function pointers can be removed.
1275 ** [function ..] is equivalent to [function ..] *
1278 if (c1tid == CT_PTR && c2tid == CT_FCN)
1280 if (ctype_isFunction (ctype_realType (c1->contents.base)))
1282 c1 = ctbase_realType (ctype_getCtbaseSafe (c1->contents.base));
1287 if (c2tid == CT_PTR && c1tid == CT_FCN)
1289 if (ctype_isFunction (ctype_realType (c2->contents.base)))
1291 c2 = ctbase_realType (ctype_getCtbaseSafe (c2->contents.base));
1297 ** we allow forward declarations to structures like,
1299 ** typedef struct _t *t;
1302 ** struct _t * to match t
1305 if (context_getFlag (FLG_FORWARDDECL))
1307 if (c1tid == CT_ABST || c1tid == CT_USER)
1309 if (ctuid_isAP (c2tid))
1311 ctype ts = c2->contents.base;
1313 if (ctype_isUA (ts))
1315 typeId ttid = ctype_typeId (ts);
1316 typeId ctid = c1->contents.tid ;
1318 if (usymtab_matchForwardStruct (ctid, ttid))
1326 if (c2tid == CT_ABST || c2tid == CT_USER)
1328 if (ctuid_isAP (c1tid))
1330 ctype ts = c1->contents.base;
1332 if (ctype_isUA (ts))
1334 typeId ttid = ctype_typeId (ts);
1335 typeId ctid = c2->contents.tid ;
1337 if (usymtab_matchForwardStruct (ctid, ttid))
1355 return (cprim_closeEnough (c1->contents.prim, c2->contents.prim));
1359 return (typeId_equal (c1->contents.tid, c2->contents.tid));
1361 return (typeId_equal (c1->contents.tid, c2->contents.tid));
1363 return (cstring_equal (c1->contents.cenum->tag, c2->contents.cenum->tag));
1365 if (ctype_isVoid (c1->contents.base)
1366 || (ctype_isVoid (c2->contents.base)))
1368 if (ctype_isFunction (ctype_realType (c1->contents.base))
1369 || ctype_isFunction (ctype_realType (c2->contents.base)))
1371 return (!context_getFlag (FLG_CASTFCNPTR));
1375 return (context_getFlag (FLG_ABSTVOIDP) ||
1376 (!(ctype_isRealAbstract (c1->contents.base)) &&
1377 !(ctype_isRealAbstract (c2->contents.base))));
1382 /* Only allow one implicit function pointer. */
1384 if (!bool_equal (ctype_isRealPointer (c1->contents.base),
1385 ctype_isRealPointer (c2->contents.base))
1386 && (ctype_isRealFunction (c1->contents.base)
1387 || ctype_isRealFunction (c2->contents.base)))
1392 return (ctype_genMatch (c1->contents.base,
1393 c2->contents.base, force, arg, def));
1396 if (ctype_isVoid (c1->contents.farray->base)
1397 || ctype_isVoid (c2->contents.farray->base))
1399 return (ctype_genMatch (c1->contents.farray->base,
1400 c2->contents.farray->base,
1403 if (ctype_isVoid (c1->contents.base) || ctype_isVoid (c2->contents.base))
1405 return (ctype_genMatch (c1->contents.base, c2->contents.base, force, arg, def));
1407 return (ctype_genMatch (c1->contents.fcn->rval,
1408 c2->contents.fcn->rval,
1410 && uentryList_matchParams (c1->contents.fcn->params,
1411 c2->contents.fcn->params,
1415 if (!cstring_isEmpty (c1->contents.su->name))
1417 return (cstring_equal (c1->contents.su->name, c2->contents.su->name));
1421 if (!cstring_isEmpty (c2->contents.su->name))
1426 llcontbuglit ("ctbase_genMatch: match fields");
1430 llcontbug (message ("ctbase_genMatch: unknown type: %d\n", (int)c1tid));
1436 ** like ctbase_match, except for conjuncts:
1437 ** modifies conjuncts to match only
1441 ctbase_forceMatch (ctbase c1, ctbase c2)
1447 return (ctbase_genMatch (c1, c2, TRUE, FALSE, FALSE));
1451 ctbase_match (ctbase c1, ctbase c2) /*@modifies nothing@*/
1453 return (ctbase_genMatch (c1, c2, FALSE, FALSE, FALSE));
1457 ctbase_matchDef (ctbase c1, ctbase c2) /*@modifies nothing@*/
1459 return (ctbase_genMatch (c1, c2, FALSE, FALSE, TRUE));
1463 ctbase_matchArg (ctbase c1, ctbase c2)
1465 return (ctbase_genMatch (c1, c2, FALSE, TRUE, FALSE));
1468 static /*@out@*/ /*@only@*/ /*@notnull@*/ ctbase
1471 ctbase c = (ctbase) dmalloc (sizeof (*c));
1475 if (nctbases % 100 == 0 && nctbases > lastnc)
1477 llmsg (message ("ctbases: %d", nctbases));
1484 static /*@only@*/ ctbase
1485 ctbase_createPrim (cprim p)
1487 ctbase c = ctbase_new ();
1490 c->contents.prim = p;
1495 static /*@observer@*/ ctbase
1496 ctbase_getBool (void)
1498 /*@i@*/ return ctbase_createBool ();
1502 ctbase_createBool ()
1504 if (!ctbase_isDefined (ctbase_bool))
1506 ctbase_bool = ctbase_new ();
1507 ctbase_bool->type = CT_BOOL;
1508 ctbase_bool->contents.prim = CTX_BOOL;
1511 /*@-retalias@*/ /*@-globstate@*/
1513 /*@=retalias@*/ /*@=globstate@*/
1516 static /*@only@*/ ctbase
1517 ctbase_createUser (typeId u)
1519 ctbase c = ctbase_new ();
1522 c->contents.tid = u;
1524 llassert (typeId_isValid (u));
1529 static /*@only@*/ ctbase
1530 ctbase_createEnum (/*@keep@*/ cstring etag, /*@keep@*/ enumNameList emembers)
1532 ctbase c = ctbase_new ();
1536 if (cstring_isUndefined (etag))
1538 llcontbuglit ("Undefined enum tag!");
1542 c->contents.cenum = (tenum) dmalloc (sizeof (*c->contents.cenum));
1543 c->contents.cenum->tag = etag;
1544 c->contents.cenum->members = emembers;
1549 static /*@observer@*/ cstring
1550 ctbase_enumTag (/*@notnull@*/ ctbase ct)
1552 return (ct->contents.cenum->tag);
1555 static /*@only@*/ ctbase
1556 ctbase_createAbstract (typeId u)
1558 ctbase c = ctbase_new ();
1561 c->contents.tid = u;
1563 /* also check its abstract? */
1565 llassert (typeId_isValid (c->contents.tid));
1570 static /*@only@*/ ctbase
1571 ctbase_createUnknown (void)
1573 if (!ctbase_isDefined (ctbase_unknown))
1575 ctbase_unknown = ctbase_new ();
1576 ctbase_unknown->type = CT_UNKNOWN;
1577 ctbase_unknown->contents.prim = CTX_UNKNOWN;
1580 /*@-retalias@*/ /*@-globstate@*/
1581 return ctbase_unknown;
1582 /*@=retalias@*/ /*@=globstate@*/
1586 ** requires: result is not assigned to b
1587 ** (should copy, but no way to reclaim storage)
1590 static /*@only@*/ ctbase
1591 ctbase_makePointer (ctype b)
1593 ctbase c = ctbase_new ();
1596 c->contents.base = b;
1601 static /*@only@*/ ctbase
1602 ctbase_makeArray (ctype b)
1604 ctbase c = ctbase_new ();
1607 c->contents.base = b;
1612 static /*@notnull@*/ /*@only@*/ ctbase
1613 ctbase_makeFixedArray (ctype b, long size)
1615 ctbase c = ctbase_new ();
1617 c->type = CT_FIXEDARRAY;
1619 c->contents.farray = (tfixed) dmalloc (sizeof (*c->contents.farray));
1620 c->contents.farray->base = b;
1621 c->contents.farray->size = size;
1627 ctbase_makeFunction (ctype b, /*@only@*/ uentryList p)
1629 ctbase c = ctbase_new ();
1633 c->contents.fcn = (cfcn) dmalloc (sizeof (*c->contents.fcn));
1635 if (ctype_isFunction (b)) /* was: && ctype_isPointer (b)) */
1640 if (ctype_isPointer (b))
1642 ctb = ctype_getCtbase (ctype_baseArrayPtr (b));
1646 ctb = ctype_getCtbase (b);
1649 llassert (ctbase_isDefined (ctb));
1650 llassert (ctb->type == CT_FCN);
1652 rval = ctype_makeFunction (ctb->contents.fcn->rval, p);
1654 c->contents.fcn->rval = rval;
1655 c->contents.fcn->params = ctb->contents.fcn->params;
1656 c->contents.fcn->liveparams = FALSE;
1660 c->contents.fcn->rval = b;
1661 /*@i@*/ c->contents.fcn->params = p;
1662 c->contents.fcn->liveparams = TRUE;
1663 /*@-branchstate@*/ /* p is really released on this branch */
1667 ct = cttable_addComplex (c);
1668 return (ct); /* was: ctype_makePointer (ct)); */
1672 ctbase_makeNFFunction (ctype b, /*@only@*/ uentryList p)
1674 ctbase c = ctbase_new ();
1678 c->contents.fcn = (cfcn) dmalloc (sizeof (*c->contents.fcn));
1680 if (ctype_isFunction (b)) /* was && ctype_isPointer (b)) */
1685 if (ctype_isPointer (b))
1687 ctb = ctype_getCtbase (ctype_baseArrayPtr (b));
1691 ctb = ctype_getCtbase (b);
1694 llassert (ctbase_isDefined (ctb));
1695 llassert (ctb->type == CT_FCN);
1697 rval = ctype_makeNFParamsFunction (ctb->contents.fcn->rval, p);
1699 c->contents.fcn->rval = rval;
1700 c->contents.fcn->params = ctb->contents.fcn->params;
1701 c->contents.fcn->liveparams = FALSE;
1705 c->contents.fcn->rval = b;
1706 /*@i@*/ c->contents.fcn->params = p;
1707 c->contents.fcn->liveparams = TRUE;
1713 ct = cttable_addComplex (c);
1714 return (ct); /* was: ctype_makePointer (ct)); */
1717 static /*@only@*/ ctbase
1718 ctbase_makeLiveFunction (ctype b, /*@owned@*/ uentryList p)
1720 ctbase c = ctbase_new ();
1724 c->contents.fcn = (cfcn) dmalloc (sizeof (*c->contents.fcn));
1725 c->contents.fcn->rval = b;
1726 c->contents.fcn->params = p;
1727 c->contents.fcn->liveparams = TRUE;
1729 /*@-mustfree@*/ return (c); /*@=mustfree@*/
1732 static /*@only@*/ ctbase
1733 ctbase_makeRealFunction (ctype b, /*@dependent@*/ uentryList p)
1735 ctbase c = ctbase_new ();
1739 c->contents.fcn = (cfcn) dmalloc (sizeof (*c->contents.fcn));
1740 c->contents.fcn->rval = b;
1741 c->contents.fcn->params = p;
1742 c->contents.fcn->liveparams = FALSE;
1747 static /*@observer@*/ /*@notnull@*/ ctbase
1748 ctbase_realFunction (/*@dependent@*/ /*@notnull@*/ ctbase c)
1752 if (c->type == CT_FCN)
1757 llassert (ctbase_isFunction (c));
1759 res = ctype_getCtbase (c->contents.base);
1761 llassert (ctbase_isDefined (res));
1767 ctbase_isFunction (ctbase c)
1769 llassert (c != ctbase_undefined);
1771 if (c->type == CT_FCN)
1777 if (c->type == CT_PTR)
1779 ctbase fcn = ctype_getCtbase (ctbase_baseArrayPtr (c));
1781 return (ctbase_isDefined (fcn) && fcn->type == CT_FCN);
1788 /* doesn't copy c1 and c2 */
1790 static /*@only@*/ ctbase
1791 ctbase_makeConj (ctype c1, ctype c2, bool isExplicit)
1793 ctbase c = ctbase_new ();
1797 c->contents.conj = (tconj) dmalloc (sizeof (*c->contents.conj));
1798 c->contents.conj->a = c1;
1799 c->contents.conj->b = c2;
1800 c->contents.conj->isExplicit = isExplicit;
1806 ctbase_getConjA (/*@notnull@*/ ctbase c)
1808 llassert (c->type == CT_CONJ);
1809 return (c->contents.conj->a);
1813 ctbase_getConjB (/*@notnull@*/ ctbase c)
1815 llassert (c->type == CT_CONJ);
1816 return (c->contents.conj->b);
1820 ctbase_isExplicitConj (/*@notnull@*/ ctbase c)
1822 llassert (c->type == CT_CONJ);
1823 return (c->contents.conj->isExplicit);
1826 static /*@only@*/ ctbase
1827 ctbase_createStruct (/*@only@*/ cstring n, /*@only@*/ uentryList f)
1829 ctbase c = ctbase_new ();
1831 c->type = CT_STRUCT;
1833 c->contents.su = (tsu) dmalloc (sizeof (*c->contents.su));
1834 c->contents.su->name = n;
1835 c->contents.su->fields = f;
1840 static /*@observer@*/ uentryList
1841 ctbase_getuentryList (/*@notnull@*/ ctbase c)
1843 c = ctbase_realType (c);
1845 if (!(c->type == CT_STRUCT || c->type == CT_UNION))
1846 llfatalbug (message ("ctbase_getuentryList: bad invocation: %q", ctbase_unparse (c)));
1848 return (c->contents.su->fields);
1852 ctbase_createUnion (/*@keep@*/ cstring n, /*@only@*/ uentryList f)
1854 ctbase c = ctbase_new ();
1858 c->contents.su = (tsu) dmalloc (sizeof (*c->contents.su));
1859 c->contents.su->name = n;
1860 c->contents.su->fields = f;
1866 ctbase_baseArrayPtr (/*@notnull@*/ ctbase c)
1869 c = ctbase_realType (c);
1872 if (ct == CT_FIXEDARRAY)
1874 return c->contents.farray->base;
1878 llassert (ctuid_isAP (ct));
1880 return c->contents.base;
1885 ctbase_baseFunction (/*@notnull@*/ ctbase c)
1888 c = ctbase_realFunction (c);
1890 if (c->type != CT_FCN)
1892 llfatalbug (message ("ctbase_baseFunction: bad call: %q", ctbase_unparse (c)));
1895 return (c->contents.fcn->rval);
1899 ctbase_argsFunction (/*@notnull@*/ ctbase c)
1902 c = ctbase_realFunction (c);
1904 if (c->type != CT_FCN)
1906 llfatalbug (message ("ctbase_argsFunction: bad call: %q",
1907 ctbase_unparse (c)));
1909 return (c->contents.fcn->params);
1913 ctbase_baseisExpFcn (ctype c)
1916 c = ctype_removePointers (c);
1918 cb = ctype_getCtbase (c);
1919 llassert (ctbase_isDefined (cb));
1921 if (cb->type == CT_FCN)
1923 c = ctype_removePointers (ctype_returnValue (c));
1925 cb = ctype_getCtbase (c);
1926 llassert (ctbase_isDefined (cb));
1928 return (cb->type == CT_EXPFCN);
1934 ** ctbase_newBase behaves specially when p is a CONJ:
1936 ** c -> conj (newBase (c, p.a), p.b)
1940 ctbase_newBase (ctype c, ctype p)
1944 DPRINTF (("New base: %s / %s", ctype_unparse (c), ctype_unparse (p)));
1946 cb = ctype_getCtbase (c);
1948 if (ctype_isUndefined (c))
1953 if (ctype_isConj (p))
1955 ctbase pb = ctype_getCtbase (p);
1957 llassert (ctbase_isDefined (pb));
1959 if (pb->contents.conj->isExplicit)
1961 return (ctype_makeExplicitConj (ctype_newBase (c, pb->contents.conj->a),
1962 pb->contents.conj->b));
1967 return (ctype_makeConj (ctype_newBase (c, pb->contents.conj->a),
1968 pb->contents.conj->b));
1973 if (ctbase_baseisExpFcn (c))
1975 return (ctbase_newBaseExpFcn (c, p));
1978 llassert (ctbase_isDefined (cb));
1997 cbn = ctbase_newBase (cb->contents.base, p);
1998 ret = ctype_makePointer (cbn);
2003 return (ctype_makeFixedArray (ctbase_newBase (cb->contents.farray->base, p),
2004 cb->contents.farray->size));
2006 return (ctype_makeArray (ctbase_newBase (cb->contents.base, p)));
2008 return (ctype_makeRealFunction (ctbase_newBase (cb->contents.fcn->rval, p),
2009 cb->contents.fcn->params));
2011 return (ctype_makeConjAux (ctbase_newBase (cb->contents.conj->a, p),
2012 ctbase_newBase (cb->contents.conj->b, p),
2013 cb->contents.conj->isExplicit));
2015 llcontbug (message ("ctbase_newBase: bad ctbase: %q", ctbase_unparse (cb)));
2022 ctbase_newBaseExpFcn (ctype c, ctype p)
2024 ctbase cb = ctype_getCtbase (c);
2027 ctype fp = ctype_unknown;
2028 uentryList ctargs = ctype_argsFunction (c);
2031 ** okay, this is really ugly...
2033 ** pointers inside <expf> mean pointers to the function;
2034 ** pointers outside <expf> are pointers to the return value;
2035 ** because its a function there is one superfluous pointer.
2039 ** bf is a ctype, used to derived structure of cb
2042 if (!ctbase_isFunction (cb))
2043 llbuglit ("ctbase_newBaseExpFcn: expFcn -> not a function");
2045 tmpct = ctype_getBaseType (ctype_returnValue (c));
2048 ** pointers before expfcn -> p are pointers to function, not result
2052 tcb = ctype_getCtbase (tmpct);
2054 llassert (ctbase_isDefined (tcb));
2055 tmpct = tcb->contents.base;
2058 ** record pointers to base in fp
2061 while (!ctype_isUnknown (tmpct))
2063 if (ctype_isExpFcn (tmpct)) {
2064 ctbase ttcb = ctype_getCtbase (tmpct);
2067 ** evs 2000-05-16: This is necessary to deal with function pointers in parens.
2068 ** The whole function pointer parsing is a major kludge, but it seems to work,
2069 ** and I'm only embarrassed by it when I haven't look at the C spec recently...
2072 llassert (ctbase_isDefined (ttcb));
2073 tmpct = ttcb->contents.base;
2074 llassert (!ctype_isUnknown (tmpct));
2077 switch (ctype_getCtKind (tmpct))
2080 fp = ctype_makePointer (fp);
2081 /*@switchbreak@*/ break;
2083 fp = ctype_makeArray (fp);
2084 /*@switchbreak@*/ break;
2087 ctbase fbase = ctype_getCtbase (tmpct);
2089 if (ctbase_isFunction (fbase))
2091 fp = ctype_makeFunction (fp, uentryList_copy (ctargs));
2092 ctargs = ctbase_argsFunction (fbase);
2098 ("ctbase_newBaseExpFcn: fixing expfunction: bad complex type: %s [base: %q]",
2099 ctype_unparse (tmpct), ctbase_unparse (fbase)));
2106 (message ("ctbase_newBaseExpFcn: fixing expfunction: bad type: %s",
2107 ctype_unparse (tmpct)));
2111 tmpct = ctype_baseArrayPtr (tmpct);
2115 tmpct = ctype_returnValue (c);
2118 ** pointers to expf are pointers to return value
2121 while (!ctype_isExpFcn (tmpct))
2123 switch (ctype_getCtKind (tmpct))
2126 p = ctype_makePointer (p);
2127 /*@switchbreak@*/ break;
2129 p = ctype_makeArray (p);
2130 /*@switchbreak@*/ break;
2133 ctbase fbase = ctype_getCtbase (tmpct);
2135 if (ctbase_isFunction (fbase))
2137 p = ctype_makeFunction (p, uentryList_copy (ctbase_argsFunction (fbase)));
2143 ("ctbase_newBaseExpFcn: fixing expfunction: bad complex type: %s",
2144 ctype_unparse (tmpct)));
2152 (message ("ctbase_newBaseExpFcn: fixing expfunction2: bad type: %t",
2157 tmpct = ctype_baseArrayPtr (tmpct);
2163 ** pointers to fp are pointers to function type
2166 ret = ctype_makeRealFunction (p, ctargs);
2168 while (ctype_getCtKind (fp) > CTK_PLAIN)
2170 switch (ctype_getCtKind (fp))
2173 ret = ctype_makePointer (ret);
2174 /*@switchbreak@*/ break;
2176 ret = ctype_makeArray (ret);
2177 /*@switchbreak@*/ break;
2180 ctbase fbase = ctype_getCtbase (fp);
2182 if (ctbase_isFunction (fbase))
2185 ctype_makeFunction (ret,
2186 uentryList_copy (ctbase_argsFunction (fbase)));
2197 llcontbug (message ("post-fixing expfunction: bad type: %t", fp));
2201 fp = ctype_baseArrayPtr (fp);
2209 ** returns lowest level base of c: plain type
2212 static /*@notnull@*/ /*@only@*/ ctbase
2213 ctbase_getBaseType (/*@notnull@*/ ctbase c)
2227 return (ctbase_copy (c));
2231 return (ctbase_getBaseType (ctype_getCtbaseSafe (c->contents.base)));
2234 return (ctbase_getBaseType (ctype_getCtbaseSafe (c->contents.farray->base)));
2235 case CT_CONJ: /* base type of A conj branch? */
2236 return (ctbase_getBaseType (ctype_getCtbaseSafe (c->contents.conj->a)));
2238 return (ctbase_copy (c));
2241 llfatalbug (message ("ctbase_getBaseType: bad ctbase: %q", ctbase_unparse (c)));
2248 ctbase_compare (ctbase c1, ctbase c2, bool strict)
2252 if (ctbase_isUndefined (c1) || ctbase_isUndefined (c2))
2254 llcontbuglit ("ctbase_compare: undefined ctbase");
2271 return (int_compare (c1->contents.prim, c2->contents.prim));
2275 return (int_compare (c1->contents.tid, c2->contents.tid));
2278 case CT_ENUM: /* for now, keep like abstract */
2280 return (int_compare (c1->contents.tid, c2->contents.tid));
2282 return (ctype_compare (c1->contents.base, c2->contents.base));
2284 INTCOMPARERETURN (c1->contents.farray->size, c2->contents.farray->size);
2286 return (ctype_compare (c1->contents.farray->base,
2287 c2->contents.farray->base));
2289 return (ctype_compare (c1->contents.base, c2->contents.base));
2292 COMPARERETURN (ctype_compare (c1->contents.fcn->rval, c2->contents.fcn->rval));
2296 return (uentryList_compareStrict (c1->contents.fcn->params,
2297 c2->contents.fcn->params));
2301 return (uentryList_compareParams (c1->contents.fcn->params,
2302 c2->contents.fcn->params));
2306 return (ctype_compare (c1->contents.base, c2->contents.base));
2309 return (uentryList_compareFields (c1->contents.su->fields,
2310 c2->contents.su->fields));
2313 COMPARERETURN (ctype_compare (c1->contents.conj->a,
2314 c2->contents.conj->a));
2315 COMPARERETURN (ctype_compare (c1->contents.conj->b,
2316 c2->contents.conj->b));
2317 return (bool_compare (c1->contents.conj->isExplicit,
2318 c2->contents.conj->isExplicit));
2325 ctbase_compareStrict (/*@notnull@*/ ctbase c1, /*@notnull@*/ ctbase c2)
2327 return (ctbase_compare (c1, c2, TRUE));
2330 static bool ctbase_equivStrict (/*@notnull@*/ ctbase c1, /*@notnull@*/ ctbase c2)
2332 return (ctbase_compareStrict (c1,c2) == 0);
2335 static bool ctbase_equiv (/*@notnull@*/ ctbase c1, /*@notnull@*/ ctbase c2)
2337 return (ctbase_compare (c1, c2, FALSE) == 0);
2341 ctbase_isKind (/*@notnull@*/ ctbase c, ctuid kind)
2349 return (ctbase_isKind (ctype_getCtbaseSafe (c->contents.conj->a), kind) ||
2350 ctbase_isKind (ctype_getCtbaseSafe (c->contents.conj->b), kind));
2356 ctbase_isKind2 (/*@notnull@*/ ctbase c, ctuid kind1, ctuid kind2)
2360 if (ck == kind1 || ck == kind2)
2364 return (ctbase_isKind2 (ctype_getCtbaseSafe (c->contents.conj->a), kind1, kind2) ||
2365 ctbase_isKind2 (ctype_getCtbaseSafe (c->contents.conj->b), kind1, kind2));
2371 ctbase_isAbstract (/*@notnull@*/ ctbase c)
2373 return (c->type == CT_ABST);
2376 static bool ctbase_isUA (ctbase c)
2378 return (ctbase_isDefined (c) && ((c)->type == CT_USER || (c)->type == CT_ABST));
2382 ctbase_almostEqual (ctbase c1, ctbase c2)
2386 /* undefined types never match */
2388 if (ctbase_isUndefined (c1) || ctbase_isUndefined (c2))
2394 if (c1tid == CT_FIXEDARRAY && c2tid == CT_ARRAY)
2396 return (ctbase_almostEqual (ctype_getCtbase (c1->contents.farray->base),
2397 ctype_getCtbase (c2->contents.base)));
2400 if (c2tid == CT_FIXEDARRAY && c1tid == CT_ARRAY)
2402 return (ctbase_almostEqual (ctype_getCtbase (c1->contents.base),
2403 ctype_getCtbase (c2->contents.farray->base)));
2414 return (cprim_equal (c1->contents.prim, c2->contents.prim));
2418 return (typeId_equal (c1->contents.tid, c2->contents.tid));
2420 return (typeId_equal (c1->contents.tid, c2->contents.tid));
2422 return (cstring_equal (c1->contents.cenum->tag, c2->contents.cenum->tag));
2424 return (ctype_almostEqual (c1->contents.base, c2->contents.base));
2426 return (ctype_almostEqual (c1->contents.farray->base,
2427 c2->contents.farray->base));
2429 return (ctype_almostEqual (c1->contents.base, c2->contents.base));
2431 return (ctype_almostEqual (c1->contents.fcn->rval, c2->contents.fcn->rval)
2432 && uentryList_matchParams (c1->contents.fcn->params,
2433 c2->contents.fcn->params, FALSE, TRUE));
2436 if (!cstring_isEmpty (c1->contents.su->name))
2438 return (cstring_equal (c1->contents.su->name, c2->contents.su->name));
2442 if (!cstring_isEmpty (c2->contents.su->name))
2447 llcontbuglit ("ctbase_almostEqual: match fields");
2451 llcontbug (message ("ctbase_almostEqual: unknown type: %d\n", (int)c1tid));