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 because there is no other way in C to have a
24 ** hidden scope, besides at the file level.)
29 abst_typedef /*@null@*/ struct s_ctbase *ctbase;
31 /*@private@*/ typedef struct {
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;
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, bool p_deep);
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@*/ /*@observer@*/ ctbase
124 ctbase_realFunction (/*@notnull@*/ /*@dependent@*/ ctbase p_c) /*@*/ ;
125 static ctype ctbase_baseArrayPtr (/*@notnull@*/ ctbase p_c) /*@*/ ;
126 static ctype ctbase_baseFunction (/*@notnull@*/ ctbase p_c) /*@*/ ;
127 static /*@observer@*/ uentryList ctbase_argsFunction (/*@notnull@*/ ctbase p_c) /*@*/ ;
128 static /*@observer@*/ uentryList ctbase_getuentryList (/*@notnull@*/ ctbase p_c) /*@*/ ;
129 static ctype ctbase_newBase (ctype p_c, ctype p_p) /*@*/ ;
130 static ctype ctbase_newBaseExpFcn (ctype p_c, ctype p_p) /*@*/ ;
131 static bool ctbase_isFixedArray (/*@notnull@*/ ctbase p_c) /*@*/ ;
134 extern int cttable_lastIndex();
135 # define cttable_lastIndex() (cttab.size - 1)
141 /*@only@*/ uentryList params;
160 enumNameList members;
171 cprim prim; /* primitive */
172 typeId tid; /* abstract, user */
173 ctype base; /* ptr, array */
174 cfcn fcn; /* function */
175 tsu su; /* struct union */
176 tenum cenum; /* enum */
177 tconj conj; /* conj */
178 tfixed farray; /* fixed array */
187 static /*@falsenull@*/ bool ctbase_isUA (ctbase p_c) /*@*/ ;
188 static bool ctbase_isBaseUA(ctbase p_c) /*@*/ ;
189 static typeId ctbase_typeBaseUid(ctbase p_c) /*@*/ ;
190 static bool ctbase_isKind (/*@notnull@*/ ctbase p_c, ctuid p_kind) /*@*/ ;
191 static bool ctbase_isKind2 (/*@notnull@*/ ctbase p_c, ctuid p_kind1, ctuid p_kind2) /*@*/ ;
192 static /*@only@*/ /*@notnull@*/ ctbase
193 ctbase_getBaseType (/*@notnull@*/ ctbase p_c) /*@*/ ;
195 static /*@falsenull@*/ bool ctbase_isFunction(ctbase p_c) /*@*/ ;
197 /*@constant null ctbase ctbase_undefined; @*/
198 # define ctbase_undefined ((ctbase)0)
200 static /*@owned@*/ ctbase ctbase_bool = ctbase_undefined;
201 static /*@owned@*/ ctbase ctbase_unknown = ctbase_undefined;
203 static /*@falsenull@*/ bool ctbase_isDefined (ctbase c) /*@*/
205 return ((c) != ctbase_undefined);
208 static /*@truenull@*/ bool ctbase_isUndefined (ctbase c)
210 return ((c) == ctbase_undefined);
213 static ctkind ctype_getCtKind (ctype c)
215 ctentry ce = ctype_getCtentry (c);
217 return ctentry_getKind (ce);
220 static bool ctbase_isUser (ctbase c)
222 if (ctbase_isDefined (c))
224 return (ctbase_isKind (c, CT_USER));
232 static bool ctbase_isEnum (ctbase c)
234 if (ctbase_isDefined (c))
236 return (ctbase_isKind (c, CT_ENUM));
244 static bool ctbase_isExpFcn (ctbase c)
246 if (ctbase_isDefined (c))
248 return (c->type == CT_EXPFCN);
256 static /*@falsenull@*/ bool ctbase_isConj (ctbase c)
258 if (ctbase_isDefined (c))
260 return (c->type == CT_CONJ);
268 static bool ctuid_isAP (ctuid c) /*@*/
270 return (c == CT_ARRAY || c == CT_PTR);
273 static typeId ctbase_typeId (ctbase p_c);
274 static /*@only@*/ cstring ctbase_dump (ctbase p_c);
275 static /*@only@*/ ctbase ctbase_undump (char **p_c);
276 static int ctbase_compare (ctbase p_c1, ctbase p_c2, bool p_strict);
277 static bool ctbase_matchArg (ctbase p_c1, ctbase p_c2);
278 static /*@notnull@*/ /*@only@*/ ctbase
279 ctbase_makeConj (ctype p_c1, ctype p_c2, bool p_isExplicit) /*@*/ ;
280 static ctype ctbase_getConjA (/*@notnull@*/ ctbase p_c) /*@*/ ;
281 static ctype ctbase_getConjB (/*@notnull@*/ ctbase p_c) /*@*/ ;
282 static bool ctbase_isExplicitConj (/*@notnull@*/ ctbase p_c) /*@*/ ;
283 static bool ctbase_forceMatch (ctbase p_c1, ctbase p_c2) /*@modifies p_c1, p_c2@*/ ;
284 static /*@notnull@*/ /*@only@*/ ctbase ctbase_expectFunction (ctype p_c);
285 static bool ctbase_isVoidPointer(/*@notnull@*/ /*@dependent@*/ ctbase p_c) /*@*/ ;
286 static bool ctbase_isUnion (/*@notnull@*/ /*@temp@*/ ctbase p_c) /*@*/ ;
287 static bool ctbase_isStruct (/*@notnull@*/ /*@temp@*/ ctbase p_c) /*@*/ ;
288 static /*@observer@*/ cstring ctbase_enumTag (/*@notnull@*/ ctbase p_ct) /*@*/ ;
289 static /*@only@*/ cstring ctbase_unparseNotypes (ctbase p_c) /*@*/ ;
291 static /*@out@*/ /*@notnull@*/ /*@only@*/ ctbase ctbase_new (void) /*@*/ ;
292 static int nctbases = 0;
294 static /*@notnull@*/ /*@only@*/
295 ctbase ctbase_makeLiveFunction (ctype p_b, /*@only@*/ uentryList p_p);
297 static bool ctbase_isUnnamedSU (ctbase c)
299 return (ctbase_isDefined (c)
300 && (ctbase_isStruct (c) || ctbase_isUnion (c))
301 && isFakeTag (c->contents.su->name));
304 static /*@observer@*/ ctbase ctbase_realType (ctbase c)
308 typeId uid = ctbase_typeId (c);
310 if (usymtab_isBoolType (uid))
312 return ctbase_getBool ();
316 ctbase ret = ctype_getCtbase
317 (uentry_getRealType (usymtab_getTypeEntry (ctbase_typeId (c))));
319 llassert (ret != ctbase_undefined);
330 ctbase_isVoidPointer (/*@dependent@*/ /*@notnull@*/ ctbase c)
332 ctbase r = ctbase_realType (c);
334 return (ctbase_isKind (r, CT_PTR) &&
335 ctype_isVoid (r->contents.base));
339 ctbase_isPointer (/*@notnull@*/ /*@dependent@*/ ctbase c)
341 ctbase r = ctbase_realType (c);
343 return (ctbase_isKind (r, CT_PTR));
347 ctbase_isEitherArray (/*@notnull@*/ ctbase c)
349 ctbase r = ctbase_realType (c);
351 return (ctbase_isKind (r, CT_ARRAY)
352 || ctbase_isKind (r, CT_FIXEDARRAY));
356 ctbase_isFixedArray (/*@notnull@*/ ctbase c)
358 ctbase r = ctbase_realType (c);
360 return (ctbase_isKind (r, CT_FIXEDARRAY));
364 ctbase_isStruct (/*@notnull@*/ ctbase c)
366 ctbase r = ctbase_realType (c);
368 return (ctbase_isKind (r, CT_STRUCT));
372 ctbase_isUnion (/*@notnull@*/ ctbase c)
374 ctbase r = ctbase_realType (c);
376 return (ctbase_isKind (r, CT_UNION));
380 ** clean this up -> typeTable should store ctype
384 ctbase_typeBaseUid (ctbase c)
388 if (ctbase_isDefined (c))
394 return ctbase_typeBaseUid (ctype_getCtbase (c->contents.base));
396 else if (ct == CT_USER || ct == CT_ABST)
398 return c->contents.tid;
400 else if (ct == CT_FIXEDARRAY)
402 return ctbase_typeBaseUid (ctype_getCtbase (c->contents.farray->base));
406 llcontbuglit ("ctbase_typeBaseUid: bad call");
407 return typeId_invalid;
410 return typeId_invalid;
414 ctbase_isBaseUA (ctbase c)
418 if (ctbase_isDefined (c))
424 return ctbase_isBaseUA (ctype_getCtbase (c->contents.base));
426 else if (ct == CT_FIXEDARRAY)
428 return ctbase_isBaseUA (ctype_getCtbase (c->contents.farray->base));
431 return (ct == CT_USER || ct == CT_ABST);
437 ctbase_typeId (ctbase c)
441 return c->contents.tid;
445 if (ctbase_isConj (c))
447 return ctbase_typeId (ctype_getCtbase (ctbase_getConjA (c)));
451 llcontbug (message ("ctbase_typeId: bad call: %q", ctbase_unparse (c)));
452 return typeId_invalid;
457 static /*@only@*/ cstring
458 ctbase_unparse (ctbase c)
460 if (ctbase_isUndefined (c)) {
461 return cstring_makeLiteral ("<<undef>>");
467 return cstring_makeLiteral ("?");
469 return cstring_copy (context_printBoolName ());
471 return (cprim_unparse (c->contents.prim));
473 return (usymtab_getTypeEntryName (c->contents.tid));
475 return (usymtab_getTypeEntryName (c->contents.tid));
477 return (message ("<expf: %t>", c->contents.base));
479 /* no spaces for multiple pointers */
481 if (ctype_isPointer (c->contents.base))
483 return (cstring_appendChar (cstring_copy (ctype_unparse (c->contents.base)), '*'));
487 return (message ("%t *", c->contents.base));
490 return (message ("%t [%d]", c->contents.farray->base,
491 (int) c->contents.farray->size));
493 return (message ("%t []", c->contents.base));
495 return (message ("[function (%q) returns %t]",
496 uentryList_unparseParams (c->contents.fcn->params),
497 c->contents.fcn->rval));
499 if (cstring_isDefined (c->contents.su->name) &&
500 !cstring_isEmpty (c->contents.su->name) &&
501 !isFakeTag (c->contents.su->name))
503 return (message ("struct %s", c->contents.su->name));
507 return (message ("struct { %q }",
508 uentryList_unparseAbbrev (c->contents.su->fields)));
511 if (cstring_isDefined (c->contents.su->name) &&
512 !cstring_isEmpty (c->contents.su->name) &&
513 !isFakeTag (c->contents.su->name))
515 return (message ("union %s", c->contents.su->name));
519 return (message ("union { %q }",
520 uentryList_unparseAbbrev (c->contents.su->fields)));
523 if (isFakeTag (c->contents.cenum->tag))
525 return (message ("enum { %q }",
526 enumNameList_unparseBrief (c->contents.cenum->members)));
530 return (message ("enum %s { %q }",
531 c->contents.cenum->tag,
532 enumNameList_unparseBrief (c->contents.cenum->members)));
535 if (c->contents.conj->isExplicit || context_getFlag (FLG_SHOWALLCONJS))
537 if (!ctype_isSimple (c->contents.conj->a) ||
538 !ctype_isSimple (c->contents.conj->b))
540 return (message ("<%t> | <%t>", c->contents.conj->a, c->contents.conj->b));
544 return (message ("%t | %t", c->contents.conj->a, c->contents.conj->b));
549 return (cstring_copy (ctype_unparse (c->contents.conj->a)));
556 static /*@only@*/ cstring
557 ctbase_unparseDeep (ctbase c)
559 if (ctbase_isUndefined (c))
561 return cstring_makeLiteral ("<<undef>>");
567 return cstring_makeLiteral ("?");
569 return cstring_copy (context_printBoolName ());
571 return (cprim_unparse (c->contents.prim));
573 if (cstring_isNonEmpty (c->contents.cenum->tag))
575 return (message ("enum %s { %q }",
576 c->contents.cenum->tag,
577 enumNameList_unparse (c->contents.cenum->members)));
581 return (message ("enum { %q }",
582 enumNameList_unparse (c->contents.cenum->members)));
585 return (usymtab_getTypeEntryName (c->contents.tid));
587 return (usymtab_getTypeEntryName (c->contents.tid));
589 return (message ("<expf: %t>", c->contents.base));
591 return (message ("%t *", c->contents.base));
593 return (message ("%t [%d]", c->contents.farray->base,
594 (int) c->contents.farray->size));
596 return (message ("%t []", c->contents.base));
598 return (message ("[function (%q) returns %t]",
599 uentryList_unparse (c->contents.fcn->params),
600 c->contents.fcn->rval));
602 return (message ("struct %s { ... } ", c->contents.su->name));
604 return (message ("union %s { ... }", c->contents.su->name));
606 return (message ("%t", c->contents.conj->a));
612 static /*@only@*/ cstring
613 ctbase_unparseNotypes (ctbase c)
615 llassert (ctbase_isDefined (c));
620 return cstring_makeLiteral ("?");
622 return cstring_copy (context_printBoolName ());
624 return (cprim_unparse (c->contents.prim));
626 if (typeId_isInvalid (c->contents.tid))
628 return cstring_makeLiteral ("enum");
632 return (message ("T#%d", c->contents.tid));
635 return (message ("uT#%d", c->contents.tid));
637 return (message ("aT#%d", c->contents.tid));
639 return (message ("<expf: %q >", ctbase_unparseNotypes (ctype_getCtbase (c->contents.base))));
641 return (message ("%q *", ctbase_unparseNotypes (ctype_getCtbase (c->contents.base))));
643 return (message ("%q []", ctbase_unparseNotypes (ctype_getCtbase (c->contents.base))));
645 return (message ("[function (%d) returns %q]", uentryList_size (c->contents.fcn->params),
646 ctbase_unparseNotypes (ctype_getCtbase (c->contents.fcn->rval))));
648 return (message ("struct %s", c->contents.su->name));
650 return (message ("union %s", c->contents.su->name));
652 return (message ("[enumlist]"));
654 return (message ("%q/%q",
655 ctbase_unparseNotypes (ctype_getCtbase (c->contents.conj->a)),
656 ctbase_unparseNotypes (ctype_getCtbase (c->contents.conj->b))));
662 static /*@only@*/ cstring
663 ctbase_unparseDeclaration (ctbase c, /*@only@*/ cstring name) /*@*/
665 if (ctbase_isUndefined (c))
673 return (message ("? %q", name));
675 return (message ("%s %q", context_printBoolName (), name));
677 return (message ("%q %q", cprim_unparse (c->contents.prim), name));
680 return (message ("%q %q", usymtab_getTypeEntryName (c->contents.tid), name));
682 llcontbuglit ("ctbase_unparseDeclaration: expfcn");
685 if (ctype_isFunction (c->contents.base))
687 return ctbase_unparseDeclaration (ctype_getCtbase (c->contents.base), name);
691 cstring s = cstring_prependChar ('*', name);
692 cstring ret = ctbase_unparseDeclaration (ctype_getCtbase (c->contents.base), s);
697 return (message ("%q[%d]",
698 ctbase_unparseDeclaration (ctype_getCtbase (c->contents.farray->base), name),
699 (int) c->contents.farray->size));
701 return (message ("%q[]",
702 ctbase_unparseDeclaration (ctype_getCtbase (c->contents.base), name)));
705 cstring s = message ("%q(%q)", name,
706 uentryList_unparseParams (c->contents.fcn->params));
708 return (ctbase_unparseDeclaration
709 (ctype_getCtbase (c->contents.fcn->rval), s));
712 if (cstring_isDefined (c->contents.su->name) &&
713 !cstring_isEmpty (c->contents.su->name) &&
714 !isFakeTag (c->contents.su->name))
716 return (message ("struct %s %q", c->contents.su->name, name));
720 return (message ("struct { %q } %q",
721 uentryList_unparseAbbrev (c->contents.su->fields),
725 if (cstring_isDefined (c->contents.su->name) &&
726 !cstring_isEmpty (c->contents.su->name) &&
727 !isFakeTag (c->contents.su->name))
729 return (message ("union %s %q", c->contents.su->name, name));
733 return (message ("union { %q } %q",
734 uentryList_unparseAbbrev (c->contents.su->fields),
738 if (isFakeTag (c->contents.cenum->tag))
740 return (message ("enum { %q } %q",
741 enumNameList_unparseBrief (c->contents.cenum->members),
746 return (message ("enum %s { %q } %q",
747 c->contents.cenum->tag,
748 enumNameList_unparseBrief (c->contents.cenum->members),
752 if (c->contents.conj->isExplicit || context_getFlag (FLG_SHOWALLCONJS))
754 if (!ctype_isSimple (c->contents.conj->a) ||
755 !ctype_isSimple (c->contents.conj->b))
757 cstring name1 = cstring_copy (name);
762 ctbase_unparseDeclaration
763 (ctype_getCtbase (c->contents.conj->a), name1),
764 ctbase_unparseDeclaration
765 (ctype_getCtbase (c->contents.conj->b), name)));
769 cstring s1 = ctbase_unparseDeclaration (ctype_getCtbase (c->contents.conj->a),
770 cstring_copy (name));
772 (message ("%q | %q", s1,
773 ctbase_unparseDeclaration (ctype_getCtbase (c->contents.conj->b),
780 return (cstring_copy (ctype_unparse (c->contents.conj->a)));
787 static ctbase ctbase_undump (d_char *c)
797 return (ctbase_undefined);
799 return (ctbase_createUnknown ());
801 return (ctbase_createBool ());
803 res = ctbase_createPrim (cprim_fromInt (reader_getInt (c)));
804 reader_checkChar (c, '|');
807 res = ctbase_createUser (typeId_fromInt (reader_getInt (c)));
808 reader_checkChar (c, '|');
811 res = ctbase_createAbstract (typeId_fromInt (reader_getInt (c)));
812 reader_checkChar (c, '|');
815 res = ctbase_makePointer (ctype_undump (c));
816 reader_checkChar (c, '|');
819 res = ctbase_makeArray (ctype_undump (c));
820 reader_checkChar (c, '|');
824 ctype ct = ctype_undump (c);
827 reader_checkChar (c, '/');
828 size = reader_getInt (c);
829 reader_checkChar (c, '|');
830 return (ctbase_makeFixedArray (ct, size));
835 char *lp = strchr (*c, '(');
837 llassertfatal (lp != NULL);
840 ct = ctype_undump (c);
843 return (ctbase_makeLiveFunction (ct, uentryList_undump (c)));
850 char *lc = strchr (*c, '{');
852 llassert (lc != NULL);
855 sname = mstring_copy (*c);
863 i = (unsigned) atoi (sname + 1);
868 fields = uentryList_undumpFields (c, g_currentloc);
870 ctb = ctbase_createStruct (cstring_fromCharsO (sname), fields);
876 char *lc = strchr (*c, '{');
878 llassert (lc != NULL);
881 sname = mstring_copy (*c);
882 llassert (sname != NULL);
890 i = (unsigned) atoi (sname + 1);
894 return (ctbase_createUnion (cstring_fromCharsO (sname),
895 uentryList_undumpFields (c, g_currentloc)));
901 char *lc = strchr (*c, '{');
903 llassert (lc != NULL);
906 sname = mstring_copy (*c);
913 i = (unsigned) atoi (sname + 1);
917 ret = ctbase_createEnum (cstring_fromCharsO (sname),
918 enumNameList_undump (c));
926 isExplicit = bool_fromInt (reader_getInt (c));
927 reader_checkChar (c, '.');
928 c1 = ctype_undump (c);
929 reader_checkChar (c, '/');
930 c2 = ctype_undump (c);
931 reader_checkChar (c, '|');
933 return (ctbase_makeConj (c1, c2, isExplicit));
939 message ("Bad Library line (type): %s", cstring_fromChars (*c)));
946 return ctbase_createUnknown ();
950 /* first letter of c encodes type: */
966 static /*@only@*/ cstring
967 ctbase_dump (ctbase c)
969 if (!ctbase_isDefined (c))
971 return cstring_makeLiteral ("?");
977 return cstring_makeLiteral ("u");
979 return cstring_makeLiteral ("b");
981 return (message ("p%d|", c->contents.prim));
983 return (message ("s%d|",
984 usymtab_convertId (c->contents.tid)));
986 return (message ("a%d|", usymtab_convertId (c->contents.tid)));
988 return (message ("t%q|", ctype_dump (c->contents.base)));
990 return (message ("y%q|", ctype_dump (c->contents.base)));
992 return (message ("F%q/%d|",
993 ctype_dump (c->contents.farray->base),
994 (int) c->contents.farray->size));
996 DPRINTF (("Dump function: %s", ctbase_unparse (c)));
997 return (message ("f%q (%q)", ctype_dump (c->contents.fcn->rval),
998 uentryList_dumpParams (c->contents.fcn->params)));
1000 return (message ("S%s{%q}", c->contents.su->name,
1001 uentryList_dumpFields (c->contents.su->fields)));
1003 return (message ("U%s{%q}", c->contents.su->name,
1004 uentryList_dumpFields (c->contents.su->fields)));
1009 if (cstring_isNonEmpty (c->contents.cenum->tag))
1011 s = message ("e%s{%q}",
1012 c->contents.cenum->tag,
1013 enumNameList_dump (c->contents.cenum->members));
1017 s = message ("e{%q}",
1018 enumNameList_dump (c->contents.cenum->members));
1023 return (message ("C%d.%q/%q|",
1024 bool_toInt (c->contents.conj->isExplicit),
1025 ctype_dump (c->contents.conj->a),
1026 ctype_dump (c->contents.conj->b)));
1028 /* should clean them up! */
1029 return (cstring_makeLiteral ("?"));
1031 llcontbug (message ("Cannot dump: %q", ctbase_unparse (c)));
1032 return (message ("u"));
1039 static /*@only@*/ ctbase
1040 ctbase_copy (/*@notnull@*/ ctbase c)
1045 return (ctbase_createUnknown ());
1047 return (ctbase_createBool ());
1049 return (ctbase_createEnum (cstring_copy (c->contents.cenum->tag),
1050 enumNameList_copy (c->contents.cenum->members)));
1052 return (ctbase_createPrim (c->contents.prim));
1054 return (ctbase_createUser (c->contents.tid));
1056 return (ctbase_createAbstract (c->contents.tid));
1058 return (ctbase_expectFunction (c->contents.base));
1060 return (ctbase_makePointer (c->contents.base));
1062 return (ctbase_makeArray (c->contents.base));
1064 return (ctbase_makeLiveFunction (c->contents.fcn->rval,
1065 uentryList_copy (c->contents.fcn->params)));
1067 return (ctbase_createStruct (cstring_copy (c->contents.su->name),
1068 uentryList_copy (c->contents.su->fields)));
1070 return (ctbase_createUnion (cstring_copy (c->contents.su->name),
1071 uentryList_copy (c->contents.su->fields)));
1073 /*@i@*/ return (c); /* not a real copy for conj's */
1075 llbug (message ("ctbase_copy: %q", ctbase_unparse (c)));
1082 ctbase_elist (ctbase c)
1084 llassert (ctbase_isDefined (c));
1085 llassert (c->type == CT_ENUM);
1087 return (c->contents.cenum->members);
1091 ctbase_free (/*@only@*/ ctbase c)
1093 if (c == ctbase_bool || c == ctbase_unknown)
1095 /*@-mustfree@*/ return; /*@=mustfree@*/
1101 if (ctbase_isDefined (c))
1129 /*@i32@*/ /* uentryList_free (c->contents.fcn->params); */
1134 cstring_free (c->contents.su->name);
1135 uentryList_free (c->contents.su->fields);
1139 /* Don't bree conj's, */
1149 ** c should be * <unknown>
1152 static /*@only@*/ ctbase
1153 ctbase_expectFunction (ctype c)
1155 ctbase f = ctbase_new ();
1157 f->type = CT_EXPFCN;
1158 f->contents.base = c;
1164 ctbase_genMatch (ctbase c1, ctbase c2, bool force, bool arg, bool def, bool deep)
1168 /* undefined types never match */
1170 if (ctbase_isUndefined (c1) || ctbase_isUndefined (c2))
1173 /* abstract types match user types of same name */
1175 c1 = ctbase_realType (c1);
1176 c2 = ctbase_realType (c2);
1178 DPRINTF (("Matching: %s / %s", ctbase_unparse (c1),
1179 ctbase_unparse (c2)));
1184 if (c1tid == CT_CONJ)
1186 return (ctbase_genMatch (ctype_getCtbase (c1->contents.conj->a), c2,
1187 force, arg, def, deep)
1188 || ctbase_genMatch (ctype_getCtbase (c1->contents.conj->b), c2,
1189 force, arg, def, deep));
1192 if (c2tid == CT_CONJ)
1194 return (ctbase_genMatch (c1, ctype_getCtbase (c2->contents.conj->a),
1195 force, arg, def, deep)
1196 || ctbase_genMatch (c1, ctype_getCtbase (c2->contents.conj->b),
1197 force, arg, def, deep));
1201 ** if the types don't match, there are some special cases...
1206 /* unknowns match anything */
1208 if (c1tid == CT_UNKNOWN || c2tid == CT_UNKNOWN)
1213 if (c1tid == CT_FIXEDARRAY
1214 && (c2tid == CT_ARRAY || (!def && c2tid == CT_PTR)))
1216 if (ctype_isVoid (c2->contents.base))
1218 return (context_getFlag (FLG_ABSTVOIDP) ||
1219 (!(ctype_isRealAbstract (c1->contents.farray->base)) &&
1220 !(ctype_isRealAbstract (c2->contents.base))));
1223 return (ctbase_genMatch (ctype_getCtbase (c1->contents.farray->base),
1224 ctype_getCtbase (c2->contents.base),
1225 force, arg, def, deep));
1229 if (c2tid == CT_FIXEDARRAY
1230 && (c1tid == CT_ARRAY || (!def && c1tid == CT_PTR)))
1232 if (ctype_isVoid (c1->contents.base))
1234 return (context_getFlag (FLG_ABSTVOIDP) ||
1235 (!(ctype_isRealAbstract (c2->contents.farray->base)) &&
1236 !(ctype_isRealAbstract (c1->contents.base))));
1239 return (ctbase_genMatch (ctype_getCtbase (c1->contents.base),
1240 ctype_getCtbase (c2->contents.farray->base),
1241 force, arg, def, deep));
1244 /* evs 2000-07-25: Bool's may match user/abstract types */
1246 if ((c1tid == CT_BOOL
1247 && (c2tid == CT_PRIM && cprim_isInt (c2->contents.prim))) ||
1249 && (c1tid == CT_PRIM && cprim_isInt (c1->contents.prim))))
1251 return (context_msgBoolInt ());
1254 if ((c1tid == CT_BOOL && (c2tid == CT_ABST || c2tid == CT_USER))) {
1255 ctype t2c = c2->contents.base;
1257 return (ctype_isBool (t2c));
1260 if ((c2tid == CT_BOOL && (c1tid == CT_ABST || c1tid == CT_USER))) {
1261 ctype t1c = c1->contents.base;
1263 return (ctype_isBool (t1c));
1266 if ((c1tid == CT_ENUM
1267 && (c2tid == CT_PRIM && cprim_isInt (c2->contents.prim))) ||
1269 && (c1tid == CT_PRIM && cprim_isInt (c1->contents.prim))))
1271 return (context_msgEnumInt ());
1275 ** arrays and pointers...yuk!
1277 ** Considered equivalent except in definitions.
1278 ** (e.g., function parameters are equivalent)
1284 if (ctuid_isAP (c1tid) && ctuid_isAP (c2tid))
1291 ** Function pointers can be removed.
1293 ** [function ..] is equivalent to [function ..] *
1296 if (c1tid == CT_PTR && c2tid == CT_FCN)
1298 if (ctype_isFunction (ctype_realType (c1->contents.base)))
1300 c1 = ctbase_realType (ctype_getCtbaseSafe (c1->contents.base));
1305 if (c2tid == CT_PTR && c1tid == CT_FCN)
1307 if (ctype_isFunction (ctype_realType (c2->contents.base)))
1309 c2 = ctbase_realType (ctype_getCtbaseSafe (c2->contents.base));
1315 ** we allow forward declarations to structures like,
1317 ** typedef struct _t *t;
1320 ** struct _t * to match t
1323 if (context_getFlag (FLG_FORWARDDECL))
1325 if (c1tid == CT_ABST || c1tid == CT_USER)
1327 if (ctuid_isAP (c2tid))
1329 ctype ts = c2->contents.base;
1331 if (ctype_isUA (ts))
1333 typeId ttid = ctype_typeId (ts);
1334 typeId ctid = c1->contents.tid ;
1336 if (usymtab_matchForwardStruct (ctid, ttid))
1344 if (c2tid == CT_ABST || c2tid == CT_USER)
1346 if (ctuid_isAP (c1tid))
1348 ctype ts = c1->contents.base;
1350 if (ctype_isUA (ts))
1352 typeId ttid = ctype_typeId (ts);
1353 typeId ctid = c2->contents.tid ;
1355 if (usymtab_matchForwardStruct (ctid, ttid))
1374 return (cprim_closeEnoughDeep (c1->contents.prim, c2->contents.prim));
1376 return (cprim_closeEnough (c1->contents.prim, c2->contents.prim));
1381 return (typeId_equal (c1->contents.tid, c2->contents.tid));
1383 return (typeId_equal (c1->contents.tid, c2->contents.tid));
1385 return (cstring_equal (c1->contents.cenum->tag, c2->contents.cenum->tag));
1387 if (ctype_isVoid (c1->contents.base)
1388 || (ctype_isVoid (c2->contents.base)))
1390 if (ctype_isFunction (ctype_realType (c1->contents.base))
1391 || ctype_isFunction (ctype_realType (c2->contents.base)))
1393 return (!context_getFlag (FLG_CASTFCNPTR));
1397 return (context_getFlag (FLG_ABSTVOIDP) ||
1398 (!(ctype_isRealAbstract (c1->contents.base)) &&
1399 !(ctype_isRealAbstract (c2->contents.base))));
1404 /* Only allow one implicit function pointer. */
1406 if (!bool_equal (ctype_isRealPointer (c1->contents.base),
1407 ctype_isRealPointer (c2->contents.base))
1408 && (ctype_isRealFunction (c1->contents.base)
1409 || ctype_isRealFunction (c2->contents.base)))
1414 return (ctype_genMatch (c1->contents.base,
1415 c2->contents.base, force, arg, def, TRUE));
1418 if (ctype_isVoid (c1->contents.farray->base)
1419 || ctype_isVoid (c2->contents.farray->base))
1421 return (ctype_genMatch (c1->contents.farray->base,
1422 c2->contents.farray->base,
1423 force, arg, def, deep));
1425 if (ctype_isVoid (c1->contents.base) || ctype_isVoid (c2->contents.base))
1427 return (ctype_genMatch (c1->contents.base, c2->contents.base, force, arg, def, TRUE));
1429 return (ctype_genMatch (c1->contents.fcn->rval,
1430 c2->contents.fcn->rval,
1431 force, arg, def, TRUE)
1432 && uentryList_matchParams (c1->contents.fcn->params,
1433 c2->contents.fcn->params,
1437 DPRINTF (("Struct: %s / %s",
1438 c1->contents.su->name,
1439 c2->contents.su->name));
1441 if (isFakeTag (c1->contents.su->name)
1442 && isFakeTag (c2->contents.su->name))
1444 /* Both fake tags, check structure */
1445 if (cstring_equal (c1->contents.su->name, c2->contents.su->name))
1451 return uentryList_matchFields (c1->contents.su->fields,
1452 c2->contents.su->fields);
1457 if (!cstring_isEmpty (c1->contents.su->name))
1459 return (cstring_equal (c1->contents.su->name, c2->contents.su->name));
1463 if (!cstring_isEmpty (c2->contents.su->name))
1468 llcontbuglit ("ctbase_genMatch: match fields");
1473 llcontbug (message ("ctbase_genMatch: unknown type: %d\n", (int)c1tid));
1479 ** like ctbase_match, except for conjuncts:
1480 ** modifies conjuncts to match only
1484 ctbase_forceMatch (ctbase c1, ctbase c2) /*@modifies c1, c2@*/
1486 return (ctbase_genMatch (c1, c2, TRUE, FALSE, FALSE, FALSE));
1490 ctbase_match (ctbase c1, ctbase c2) /*@modifies nothing@*/
1492 return (ctbase_genMatch (c1, c2, FALSE, FALSE, FALSE, FALSE));
1496 ctbase_matchDef (ctbase c1, ctbase c2) /*@modifies nothing@*/
1498 return (ctbase_genMatch (c1, c2, FALSE, FALSE, TRUE, FALSE));
1502 ctbase_matchArg (ctbase c1, ctbase c2)
1504 return (ctbase_genMatch (c1, c2, FALSE, TRUE, FALSE, FALSE));
1507 static /*@out@*/ /*@only@*/ /*@notnull@*/ ctbase
1510 ctbase c = (ctbase) dmalloc (sizeof (*c));
1514 if (nctbases % 100 == 0 && nctbases > lastnc)
1516 llmsg (message ("ctbases: %d", nctbases));
1523 static /*@only@*/ ctbase
1524 ctbase_createPrim (cprim p)
1526 ctbase c = ctbase_new ();
1529 c->contents.prim = p;
1534 static /*@observer@*/ ctbase
1535 ctbase_getBool (void)
1537 /*@i@*/ return ctbase_createBool ();
1541 ctbase_createBool ()
1543 if (!ctbase_isDefined (ctbase_bool))
1545 ctbase_bool = ctbase_new ();
1546 ctbase_bool->type = CT_BOOL;
1547 ctbase_bool->contents.prim = CTX_BOOL;
1550 /*@-retalias@*/ /*@-globstate@*/
1552 /*@=retalias@*/ /*@=globstate@*/
1555 static /*@only@*/ ctbase
1556 ctbase_createUser (typeId u)
1558 ctbase c = ctbase_new ();
1561 c->contents.tid = u;
1563 llassert (typeId_isValid (u));
1568 static /*@only@*/ ctbase
1569 ctbase_createEnum (/*@keep@*/ cstring etag, /*@keep@*/ enumNameList emembers)
1571 ctbase c = ctbase_new ();
1575 if (cstring_isUndefined (etag))
1577 llcontbuglit ("Undefined enum tag!");
1581 c->contents.cenum = (tenum) dmalloc (sizeof (*c->contents.cenum));
1582 c->contents.cenum->tag = etag;
1583 c->contents.cenum->members = emembers;
1588 static /*@observer@*/ cstring
1589 ctbase_enumTag (/*@notnull@*/ ctbase ct)
1591 return (ct->contents.cenum->tag);
1594 static /*@only@*/ ctbase
1595 ctbase_createAbstract (typeId u)
1597 ctbase c = ctbase_new ();
1600 c->contents.tid = u;
1602 /* also check its abstract? */
1604 llassert (typeId_isValid (c->contents.tid));
1609 static /*@only@*/ ctbase
1610 ctbase_createUnknown (void)
1612 if (!ctbase_isDefined (ctbase_unknown))
1614 ctbase_unknown = ctbase_new ();
1615 ctbase_unknown->type = CT_UNKNOWN;
1616 ctbase_unknown->contents.prim = CTX_UNKNOWN;
1619 /*@-retalias@*/ /*@-globstate@*/
1620 return ctbase_unknown;
1621 /*@=retalias@*/ /*@=globstate@*/
1625 ** requires: result is not assigned to b
1626 ** (should copy, but no way to reclaim storage)
1629 static /*@only@*/ ctbase
1630 ctbase_makePointer (ctype b)
1632 ctbase c = ctbase_new ();
1635 c->contents.base = b;
1640 static /*@only@*/ ctbase
1641 ctbase_makeArray (ctype b)
1643 ctbase c = ctbase_new ();
1646 c->contents.base = b;
1651 static /*@notnull@*/ /*@only@*/ ctbase
1652 ctbase_makeFixedArray (ctype b, long size)
1654 ctbase c = ctbase_new ();
1656 c->type = CT_FIXEDARRAY;
1658 c->contents.farray = (tfixed) dmalloc (sizeof (*c->contents.farray));
1659 c->contents.farray->base = b;
1660 c->contents.farray->size = size;
1666 ctbase_makeFunction (ctype b, /*@only@*/ uentryList p)
1668 ctbase c = ctbase_new ();
1672 c->contents.fcn = (cfcn) dmalloc (sizeof (*c->contents.fcn));
1674 if (ctype_isFunction (b)) /* was: && ctype_isPointer (b)) */
1679 if (ctype_isPointer (b))
1681 ctb = ctype_getCtbase (ctype_baseArrayPtr (b));
1685 ctb = ctype_getCtbase (b);
1688 llassert (ctbase_isDefined (ctb));
1689 llassert (ctb->type == CT_FCN);
1691 rval = ctype_makeFunction (ctb->contents.fcn->rval, p);
1693 c->contents.fcn->rval = rval;
1694 c->contents.fcn->params = uentryList_copy (ctb->contents.fcn->params); /* no copy before */
1698 c->contents.fcn->rval = b;
1699 c->contents.fcn->params = uentryList_copy (p); /* no copy before */
1700 /*@-branchstate@*/ /* p is really released on this branch */
1704 ct = cttable_addComplex (c);
1705 return (ct); /* was: ctype_makePointer (ct)); */
1709 ctbase_makeNFFunction (ctype b, /*@only@*/ uentryList p)
1711 ctbase c = ctbase_new ();
1715 c->contents.fcn = (cfcn) dmalloc (sizeof (*c->contents.fcn));
1717 if (ctype_isFunction (b)) /* was && ctype_isPointer (b)) */
1722 if (ctype_isPointer (b))
1724 ctb = ctype_getCtbase (ctype_baseArrayPtr (b));
1728 ctb = ctype_getCtbase (b);
1731 llassert (ctbase_isDefined (ctb));
1732 llassert (ctb->type == CT_FCN);
1734 rval = ctype_makeNFParamsFunction (ctb->contents.fcn->rval, p);
1736 c->contents.fcn->rval = rval;
1737 c->contents.fcn->params = uentryList_copy (ctb->contents.fcn->params);
1741 c->contents.fcn->rval = b;
1742 c->contents.fcn->params = uentryList_copy (p);
1747 ct = cttable_addComplex (c);
1748 return (ct); /* was: ctype_makePointer (ct)); */
1751 static /*@only@*/ ctbase
1752 ctbase_makeLiveFunction (ctype b, /*@only@*/ uentryList p)
1754 ctbase c = ctbase_new ();
1758 c->contents.fcn = (cfcn) dmalloc (sizeof (*c->contents.fcn));
1759 c->contents.fcn->rval = b;
1760 c->contents.fcn->params = p;
1762 /*@-mustfree@*/ return (c); /*@=mustfree@*/
1765 static /*@observer@*/ /*@notnull@*/ ctbase
1766 ctbase_realFunction (/*@dependent@*/ /*@notnull@*/ ctbase c)
1770 if (c->type == CT_FCN)
1775 llassert (ctbase_isFunction (c));
1777 res = ctype_getCtbase (c->contents.base);
1779 llassert (ctbase_isDefined (res));
1785 ctbase_isFunction (ctbase c)
1787 llassert (c != ctbase_undefined);
1789 if (c->type == CT_FCN)
1795 if (c->type == CT_PTR)
1797 ctbase fcn = ctype_getCtbase (ctbase_baseArrayPtr (c));
1799 return (ctbase_isDefined (fcn) && fcn->type == CT_FCN);
1806 /* doesn't copy c1 and c2 */
1808 static /*@only@*/ ctbase
1809 ctbase_makeConj (ctype c1, ctype c2, bool isExplicit)
1811 ctbase c = ctbase_new ();
1815 c->contents.conj = (tconj) dmalloc (sizeof (*c->contents.conj));
1816 c->contents.conj->a = c1;
1817 c->contents.conj->b = c2;
1818 c->contents.conj->isExplicit = isExplicit;
1824 ctbase_getConjA (/*@notnull@*/ ctbase c)
1826 llassert (c->type == CT_CONJ);
1827 return (c->contents.conj->a);
1831 ctbase_getConjB (/*@notnull@*/ ctbase c)
1833 llassert (c->type == CT_CONJ);
1834 return (c->contents.conj->b);
1838 ctbase_isExplicitConj (/*@notnull@*/ ctbase c)
1840 llassert (c->type == CT_CONJ);
1841 return (c->contents.conj->isExplicit);
1844 static /*@only@*/ ctbase
1845 ctbase_createStruct (/*@only@*/ cstring n, /*@only@*/ uentryList f)
1847 ctbase c = ctbase_new ();
1849 c->type = CT_STRUCT;
1851 c->contents.su = (tsu) dmalloc (sizeof (*c->contents.su));
1852 c->contents.su->name = n;
1853 c->contents.su->fields = f;
1858 static /*@observer@*/ uentryList
1859 ctbase_getuentryList (/*@notnull@*/ ctbase c)
1861 c = ctbase_realType (c);
1863 if (!(c->type == CT_STRUCT || c->type == CT_UNION))
1864 llfatalbug (message ("ctbase_getuentryList: bad invocation: %q", ctbase_unparse (c)));
1866 return (c->contents.su->fields);
1870 ctbase_createUnion (/*@keep@*/ cstring n, /*@only@*/ uentryList f)
1872 ctbase c = ctbase_new ();
1876 c->contents.su = (tsu) dmalloc (sizeof (*c->contents.su));
1877 c->contents.su->name = n;
1878 c->contents.su->fields = f;
1884 ctbase_baseArrayPtr (/*@notnull@*/ ctbase c)
1887 c = ctbase_realType (c);
1890 if (ct == CT_FIXEDARRAY)
1892 return c->contents.farray->base;
1896 llassert (ctuid_isAP (ct));
1898 return c->contents.base;
1903 ctbase_baseFunction (/*@notnull@*/ ctbase c)
1906 c = ctbase_realFunction (c);
1908 if (c->type != CT_FCN)
1910 llfatalbug (message ("ctbase_baseFunction: bad call: %q", ctbase_unparse (c)));
1913 return (c->contents.fcn->rval);
1917 ctbase_argsFunction (/*@notnull@*/ ctbase c)
1920 c = ctbase_realFunction (c);
1922 if (c->type != CT_FCN)
1924 llfatalbug (message ("ctbase_argsFunction: bad call: %q",
1925 ctbase_unparse (c)));
1927 return (c->contents.fcn->params);
1931 ctbase_baseisExpFcn (ctype c)
1934 c = ctype_removePointers (c);
1936 cb = ctype_getCtbase (c);
1937 llassert (ctbase_isDefined (cb));
1939 if (cb->type == CT_FCN)
1941 c = ctype_removePointers (ctype_getReturnType (c));
1943 cb = ctype_getCtbase (c);
1944 llassert (ctbase_isDefined (cb));
1946 return (cb->type == CT_EXPFCN);
1952 ** ctbase_newBase behaves specially when p is a CONJ:
1954 ** c -> conj (newBase (c, p.a), p.b)
1958 ctbase_newBase (ctype c, ctype p)
1962 DPRINTF (("New base: %s / %s", ctype_unparse (c), ctype_unparse (p)));
1964 if (ctype_isUndefined (c) || ctype_isUnknown (c))
1969 cb = ctype_getCtbase (c);
1971 if (ctype_isConj (p))
1973 ctbase pb = ctype_getCtbase (p);
1975 llassert (ctbase_isDefined (pb));
1977 if (pb->contents.conj->isExplicit)
1979 return (ctype_makeExplicitConj (ctype_newBase (c, pb->contents.conj->a),
1980 pb->contents.conj->b));
1985 return (ctype_makeConj (ctype_newBase (c, pb->contents.conj->a),
1986 pb->contents.conj->b));
1991 if (ctbase_baseisExpFcn (c))
1993 return (ctbase_newBaseExpFcn (c, p));
1996 llassert (ctbase_isDefined (cb));
2015 cbn = ctbase_newBase (cb->contents.base, p);
2016 ret = ctype_makePointer (cbn);
2021 return (ctype_makeFixedArray (ctbase_newBase (cb->contents.farray->base, p),
2022 cb->contents.farray->size));
2024 return (ctype_makeArray (ctbase_newBase (cb->contents.base, p)));
2026 return (ctype_makeRawFunction (ctbase_newBase (cb->contents.fcn->rval, p),
2027 cb->contents.fcn->params));
2029 return (ctype_makeConjAux (ctbase_newBase (cb->contents.conj->a, p),
2030 ctbase_newBase (cb->contents.conj->b, p),
2031 cb->contents.conj->isExplicit));
2033 llcontbug (message ("ctbase_newBase: bad ctbase: %q", ctbase_unparse (cb)));
2040 ctbase_newBaseExpFcn (ctype c, ctype p)
2042 ctbase cb = ctype_getCtbase (c);
2045 ctype fp = ctype_unknown;
2046 uentryList ctargs = ctype_argsFunction (c);
2049 ** okay, this is really ugly...
2051 ** pointers inside <expf> mean pointers to the function;
2052 ** pointers outside <expf> are pointers to the return value;
2053 ** because its a function there is one superfluous pointer.
2057 ** bf is a ctype, used to derived structure of cb
2060 if (!ctbase_isFunction (cb))
2061 llbuglit ("ctbase_newBaseExpFcn: expFcn -> not a function");
2063 tmpct = ctype_getBaseType (ctype_getReturnType (c));
2066 ** pointers before expfcn -> p are pointers to function, not result
2070 tcb = ctype_getCtbase (tmpct);
2072 llassert (ctbase_isDefined (tcb));
2073 tmpct = tcb->contents.base;
2076 ** record pointers to base in fp
2079 while (!ctype_isUnknown (tmpct))
2081 if (ctype_isExpFcn (tmpct)) {
2082 ctbase ttcb = ctype_getCtbase (tmpct);
2085 ** evs 2000-05-16: This is necessary to deal with function pointers in parens.
2086 ** The whole function pointer parsing is a major kludge, but it seems to work,
2087 ** and I'm only embarrassed by it when I haven't look at the C spec recently...
2090 llassert (ctbase_isDefined (ttcb));
2091 tmpct = ttcb->contents.base;
2092 llassert (!ctype_isUnknown (tmpct));
2095 switch (ctype_getCtKind (tmpct))
2098 fp = ctype_makePointer (fp);
2099 /*@switchbreak@*/ break;
2101 fp = ctype_makeArray (fp);
2102 /*@switchbreak@*/ break;
2105 ctbase fbase = ctype_getCtbase (tmpct);
2107 if (ctbase_isFunction (fbase))
2109 fp = ctype_makeFunction (fp, uentryList_copy (ctargs));
2110 ctargs = ctbase_argsFunction (fbase);
2116 ("ctbase_newBaseExpFcn: fixing expfunction: bad complex type: %s [base: %q]",
2117 ctype_unparse (tmpct), ctbase_unparse (fbase)));
2124 (message ("ctbase_newBaseExpFcn: fixing expfunction: bad type: %s",
2125 ctype_unparse (tmpct)));
2129 tmpct = ctype_baseArrayPtr (tmpct);
2133 tmpct = ctype_getReturnType (c);
2136 ** pointers to expf are pointers to return value
2139 while (!ctype_isExpFcn (tmpct))
2141 switch (ctype_getCtKind (tmpct))
2144 p = ctype_makePointer (p);
2145 /*@switchbreak@*/ break;
2147 p = ctype_makeArray (p);
2148 /*@switchbreak@*/ break;
2151 ctbase fbase = ctype_getCtbase (tmpct);
2153 if (ctbase_isFunction (fbase))
2155 p = ctype_makeFunction (p, uentryList_copy (ctbase_argsFunction (fbase)));
2161 ("ctbase_newBaseExpFcn: fixing expfunction: bad complex type: %s",
2162 ctype_unparse (tmpct)));
2170 (message ("ctbase_newBaseExpFcn: fixing expfunction2: bad type: %t",
2175 tmpct = ctype_baseArrayPtr (tmpct);
2181 ** pointers to fp are pointers to function type
2184 ret = ctype_makeRawFunction (p, uentryList_copy (ctargs));
2186 while (ctype_getCtKind (fp) > CTK_PLAIN)
2188 switch (ctype_getCtKind (fp))
2191 ret = ctype_makePointer (ret);
2192 /*@switchbreak@*/ break;
2194 ret = ctype_makeArray (ret);
2195 /*@switchbreak@*/ break;
2198 ctbase fbase = ctype_getCtbase (fp);
2200 if (ctbase_isFunction (fbase))
2203 ctype_makeFunction (ret,
2204 uentryList_copy (ctbase_argsFunction (fbase)));
2215 llcontbug (message ("post-fixing expfunction: bad type: %t", fp));
2219 fp = ctype_baseArrayPtr (fp);
2227 ** returns lowest level base of c: plain type
2230 static /*@notnull@*/ /*@only@*/ ctbase
2231 ctbase_getBaseType (/*@notnull@*/ ctbase c)
2245 return (ctbase_copy (c));
2249 return (ctbase_getBaseType (ctype_getCtbaseSafe (c->contents.base)));
2252 return (ctbase_getBaseType (ctype_getCtbaseSafe (c->contents.farray->base)));
2253 case CT_CONJ: /* base type of A conj branch? */
2254 return (ctbase_getBaseType (ctype_getCtbaseSafe (c->contents.conj->a)));
2256 return (ctbase_copy (c));
2259 llfatalbug (message ("ctbase_getBaseType: bad ctbase: %q", ctbase_unparse (c)));
2266 ctbase_compare (ctbase c1, ctbase c2, bool strict)
2270 if (ctbase_isUndefined (c1) || ctbase_isUndefined (c2))
2272 llcontbuglit ("ctbase_compare: undefined ctbase");
2289 return (int_compare (c1->contents.prim, c2->contents.prim));
2293 return (int_compare (c1->contents.tid, c2->contents.tid));
2296 case CT_ENUM: /* for now, keep like abstract */
2298 return (int_compare (c1->contents.tid, c2->contents.tid));
2300 return (ctype_compare (c1->contents.base, c2->contents.base));
2302 INTCOMPARERETURN (c1->contents.farray->size, c2->contents.farray->size);
2304 return (ctype_compare (c1->contents.farray->base,
2305 c2->contents.farray->base));
2307 return (ctype_compare (c1->contents.base, c2->contents.base));
2310 COMPARERETURN (ctype_compare (c1->contents.fcn->rval, c2->contents.fcn->rval));
2314 return (uentryList_compareStrict (c1->contents.fcn->params,
2315 c2->contents.fcn->params));
2319 return (uentryList_compareParams (c1->contents.fcn->params,
2320 c2->contents.fcn->params));
2324 return (ctype_compare (c1->contents.base, c2->contents.base));
2327 /* evs 2000-07-28: this block was missing! */
2329 int ncmp = cstring_compare (c1->contents.su->name,
2330 c2->contents.su->name);
2333 if (isFakeTag (c1->contents.su->name)
2334 && isFakeTag (c2->contents.su->name)) {
2335 ; /* If they are both fake struct tags, don't require match. */
2342 DPRINTF (("Comparing fields: %s / %s",
2343 ctbase_unparse (c1),
2344 ctbase_unparse (c2)));
2346 return (uentryList_compareFields (c1->contents.su->fields,
2347 c2->contents.su->fields));
2350 COMPARERETURN (ctype_compare (c1->contents.conj->a,
2351 c2->contents.conj->a));
2352 COMPARERETURN (ctype_compare (c1->contents.conj->b,
2353 c2->contents.conj->b));
2354 return (bool_compare (c1->contents.conj->isExplicit,
2355 c2->contents.conj->isExplicit));
2362 ctbase_compareStrict (/*@notnull@*/ ctbase c1, /*@notnull@*/ ctbase c2)
2364 return (ctbase_compare (c1, c2, TRUE));
2367 static bool ctbase_equivStrict (/*@notnull@*/ ctbase c1, /*@notnull@*/ ctbase c2)
2369 return (ctbase_compareStrict (c1,c2) == 0);
2372 static bool ctbase_equiv (/*@notnull@*/ ctbase c1, /*@notnull@*/ ctbase c2)
2374 return (ctbase_compare (c1, c2, FALSE) == 0);
2378 ctbase_isKind (/*@notnull@*/ ctbase c, ctuid kind)
2386 return (ctbase_isKind (ctype_getCtbaseSafe (c->contents.conj->a), kind) ||
2387 ctbase_isKind (ctype_getCtbaseSafe (c->contents.conj->b), kind));
2393 ctbase_isKind2 (/*@notnull@*/ ctbase c, ctuid kind1, ctuid kind2)
2397 if (ck == kind1 || ck == kind2)
2401 return (ctbase_isKind2 (ctype_getCtbaseSafe (c->contents.conj->a), kind1, kind2) ||
2402 ctbase_isKind2 (ctype_getCtbaseSafe (c->contents.conj->b), kind1, kind2));
2408 ctbase_isAbstract (/*@notnull@*/ ctbase c)
2410 return (c->type == CT_ABST);
2413 static bool ctbase_isUA (ctbase c)
2415 return (ctbase_isDefined (c) && ((c)->type == CT_USER || (c)->type == CT_ABST));
2419 ctbase_almostEqual (ctbase c1, ctbase c2)
2423 /* undefined types never match */
2425 if (ctbase_isUndefined (c1) || ctbase_isUndefined (c2))
2431 if (c1tid == CT_FIXEDARRAY && c2tid == CT_ARRAY)
2433 return (ctbase_almostEqual (ctype_getCtbase (c1->contents.farray->base),
2434 ctype_getCtbase (c2->contents.base)));
2437 if (c2tid == CT_FIXEDARRAY && c1tid == CT_ARRAY)
2439 return (ctbase_almostEqual (ctype_getCtbase (c1->contents.base),
2440 ctype_getCtbase (c2->contents.farray->base)));
2451 return (cprim_equal (c1->contents.prim, c2->contents.prim));
2455 return (typeId_equal (c1->contents.tid, c2->contents.tid));
2457 return (typeId_equal (c1->contents.tid, c2->contents.tid));
2459 return (cstring_equal (c1->contents.cenum->tag, c2->contents.cenum->tag));
2461 return (ctype_almostEqual (c1->contents.base, c2->contents.base));
2463 return (ctype_almostEqual (c1->contents.farray->base,
2464 c2->contents.farray->base));
2466 return (ctype_almostEqual (c1->contents.base, c2->contents.base));
2468 return (ctype_almostEqual (c1->contents.fcn->rval, c2->contents.fcn->rval)
2469 && uentryList_matchParams (c1->contents.fcn->params,
2470 c2->contents.fcn->params, FALSE, TRUE));
2473 if (!cstring_isEmpty (c1->contents.su->name))
2475 return (cstring_equal (c1->contents.su->name, c2->contents.su->name));
2479 if (!cstring_isEmpty (c2->contents.su->name))
2484 llcontbuglit ("ctbase_almostEqual: match fields");
2488 llcontbug (message ("ctbase_almostEqual: unknown type: %d\n", (int)c1tid));
2493 /*drl added July 02, 001
2494 called by ctype_getArraySize
2497 long int ctbase_getArraySize (ctbase ctb)
2499 llassert (ctbase_isDefined (ctb) );
2501 llassert (ctbase_isFixedArray(ctb) );
2503 return (ctb->contents.farray->size);