]> andersk Git - splint.git/blame - src/ctbase.i
ADded numabstract types.
[splint.git] / src / ctbase.i
CommitLineData
885824d3 1/* ;-*-C-*-;
1b8ae690 2** Splint - annotation-assisted static program checker
3** Copyright (C) 1994-2002 University of Virginia,
4** Massachusetts Institute of Technology
885824d3 5**
1b8ae690 6** This program is free software; you can redistribute it and/or modify it
7** under the terms of the GNU General Public License as published by the
8** Free Software Foundation; either version 2 of the License, or (at your
9** option) any later version.
10**
11** This program is distributed in the hope that it will be useful, but
12** WITHOUT ANY WARRANTY; without even the implied warranty of
13** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14** General Public License for more details.
15**
16** The GNU General Public License is available from http://www.gnu.org/ or
17** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18** MA 02111-1307, USA.
885824d3 19**
1b8ae690 20** For information on splint: splint@cs.virginia.edu
21** To report a bug: splint-bug@cs.virginia.edu
22** For more information: http://www.splint.org
885824d3 23*/
24/*
25** ctbase.i
26**
27** NOTE: This is not a stand-alone source file, but is included in ctype.c.
28bf4b0b 28** (This is necessary because there is no other way in C to have a
885824d3 29** hidden scope, besides at the file level.)
30*/
31
32/*@access cprim*/
33
28bf4b0b 34abst_typedef /*@null@*/ struct s_ctbase *ctbase;
885824d3 35
e5081f8c 36/*@function static bool ctuid_isAnyUserType (sef ctuid p_cid) @*/
37# define ctuid_isAnyUserType(cid) \
38 ((cid) == CT_ABST || (cid) == CT_USER || (cid) == CT_NUMABST)
39
28bf4b0b 40/*@private@*/ typedef struct {
885824d3 41 ctkind kind;
28bf4b0b 42 ctbase ctbase;
885824d3 43 ctype base; /* type I point to (or element of array) */
44 ctype ptr; /* type of pointer to me */
45 ctype array; /* type of array of me */
46 cstring unparse; /* unparse me, if memoized */
47} *ctentry ;
48
49typedef /*@only@*/ ctentry o_ctentry;
50
28bf4b0b 51typedef struct {
885824d3 52 int size;
53 int nspace;
54 /*@relnull@*/ /*@only@*/ o_ctentry *entries;
55 /* memoize matches...maybe in context? */
56} cttable ;
57
58extern bool ctentry_isBogus (/*@sef@*/ ctentry p_c) /*@*/;
59# define ctentry_isBogus(c) \
60 ((c)->kind == CTK_INVALID || (c)->kind == CTK_DNE)
61
62static cttable cttab = { 0, 0, NULL };
63
64static /*@notnull@*/ /*@only@*/ ctbase ctbase_createAbstract (typeId p_u);
e5081f8c 65static /*@notnull@*/ /*@only@*/ ctbase ctbase_createNumAbstract (typeId p_u);
885824d3 66static /*@observer@*/ cstring ctentry_doUnparse (ctentry p_c) /*@modifies p_c@*/;
67static /*@only@*/ ctentry
68 ctentry_make (ctkind p_ctk, /*@keep@*/ ctbase p_c, ctype p_base,
69 ctype p_ptr, ctype p_array, /*@keep@*/ cstring p_unparse);
70static /*@only@*/ ctentry ctentry_makeNew (ctkind p_ctk, /*@only@*/ ctbase p_c);
71static /*@only@*/ cstring ctentry_unparse (ctentry p_c) /*@*/ ;
72
73static void cttable_grow (void);
74static ctype cttable_addDerived (ctkind p_ctk, /*@keep@*/ ctbase p_cnew, ctype p_base);
75static ctype cttable_addFull (/*@keep@*/ ctentry p_cnew);
76static bool ctentry_isInteresting (ctentry p_c) /*@*/;
37ae0b5e 77static /*@notnull@*/ /*@only@*/ ctbase ctbase_makeFixedArray (ctype p_b, size_t p_size) /*@*/ ;
d5047b91 78static bool ctbase_isAnytype (/*@notnull@*/ ctbase p_b) /*@*/ ;
885824d3 79
80/*
81** These are file-static macros (used in ctype.c). No way to
82** declare them as static in C.
83*/
84
85/*@-allmacros@*/ /*@-macrospec@*/ /*@-namechecks@*/
86# define ctentry_getBase(c) ((c)->base)
87# define ctentry_getKind(c) ((c)->kind)
88# define ctentry_getArray(c) ((c)->array)
89# define ctentry_getPtr(c) ((c)->ptr)
90# define ctentry_isArray(c) ((c)->kind == CTK_ARRAY)
91# define ctentry_isComplex(c) ((c)->kind == CTK_COMPLEX)
92# define ctentry_isPlain(c) ((c)->kind == CTK_PLAIN)
93# define ctentry_isPointer(c) ((c)->kind == CTK_PTR)
94# define ctentry_setArray(c,b) ((c)->array = (b))
95# define ctentry_setPtr(c,b) ((c)->ptr = (b))
96
97# define ctbase_fixUser(c) (c = ctbase_realType(c))
98/*@=allmacros@*/ /*@=macrospec@*/ /*@=namechecks@*/
99
100static ctype cttable_addComplex (/*@notnull@*/ /*@only@*/ ctbase p_cnew);
101static /*@observer@*/ ctbase ctype_getCtbase (ctype p_c) /*@*/ ;
102static ctype ctype_makeConjAux (ctype p_c1, ctype p_c2, bool p_isExplicit) /*@*/ ;
103static /*@notnull@*/ /*@observer@*/ ctbase ctype_getCtbaseSafe (ctype p_c) /*@*/ ;
104static /*@observer@*/ ctentry ctype_getCtentry (ctype p_c) /*@*/ ;
105static /*@observer@*/ /*@notnull@*/ ctbase
106 ctbase_realType (/*@notnull@*/ ctbase p_c) /*@*/ ;
107static bool ctbase_isPointer (/*@notnull@*/ /*@dependent@*/ ctbase p_c) /*@*/ ;
108static bool ctbase_isEitherArray (/*@notnull@*/ /*@dependent@*/ ctbase p_c) /*@*/ ;
109static /*@observer@*/ enumNameList ctbase_elist (ctbase p_c) /*@*/ ;
110static /*@only@*/ cstring ctbase_unparse (ctbase p_c) /*@*/ ;
111static /*@only@*/ cstring ctbase_unparseDeep (ctbase p_c) /*@*/ ;
112static /*@only@*/ /*@notnull@*/ ctbase ctbase_copy (/*@notnull@*/ ctbase p_c) /*@*/ ;
113static void ctbase_free (/*@only@*/ ctbase p_c);
114static /*@notnull@*/ /*@only@*/ ctbase ctbase_createPrim (cprim p_p) /*@*/ ;
115static /*@notnull@*/ /*@only@*/ ctbase ctbase_createBool (void) /*@*/ ;
116static /*@notnull@*/ /*@observer@*/ ctbase ctbase_getBool (void) /*@*/ ;
117static /*@notnull@*/ /*@only@*/ ctbase ctbase_createUser (typeId p_u) /*@*/ ;
118
119static /*@notnull@*/ /*@only@*/ ctbase
120 ctbase_createStruct (/*@only@*/ cstring p_n, /*@only@*/ uentryList p_f);
121
122static /*@notnull@*/ /*@only@*/ ctbase
123 ctbase_createUnion (/*@keep@*/ cstring p_n, /*@only@*/ uentryList p_f);
124static /*@notnull@*/ /*@only@*/ ctbase ctbase_createEnum (/*@keep@*/ cstring p_etag, /*@keep@*/ enumNameList p_emembers);
125static /*@notnull@*/ /*@only@*/ ctbase ctbase_createUnknown (void);
126static bool ctbase_match (ctbase p_c1, ctbase p_c2) /*@modifies nothing@*/;
127static bool ctbase_matchDef (ctbase p_c1, ctbase p_c2) /*@modifies nothing@*/;
a0a162cd 128static bool ctbase_genMatch (ctbase p_c1, ctbase p_c2, bool p_force, bool p_arg, bool p_def, bool p_deep);
885824d3 129static bool ctbase_isAbstract (/*@notnull@*/ ctbase p_c) /*@*/ ;
130static /*@notnull@*/ /*@only@*/ ctbase ctbase_makePointer (ctype p_b) /*@*/ ;
131static /*@notnull@*/ /*@only@*/ ctbase ctbase_makeArray (ctype p_b) /*@*/ ;
132static /*@notnull@*/ ctype
133 ctbase_makeFunction (ctype p_b, /*@only@*/ uentryList p_p) /*@*/ ;
885824d3 134static /*@notnull@*/ /*@observer@*/ ctbase
135 ctbase_realFunction (/*@notnull@*/ /*@dependent@*/ ctbase p_c) /*@*/ ;
136static ctype ctbase_baseArrayPtr (/*@notnull@*/ ctbase p_c) /*@*/ ;
137static ctype ctbase_baseFunction (/*@notnull@*/ ctbase p_c) /*@*/ ;
138static /*@observer@*/ uentryList ctbase_argsFunction (/*@notnull@*/ ctbase p_c) /*@*/ ;
139static /*@observer@*/ uentryList ctbase_getuentryList (/*@notnull@*/ ctbase p_c) /*@*/ ;
140static ctype ctbase_newBase (ctype p_c, ctype p_p) /*@*/ ;
141static ctype ctbase_newBaseExpFcn (ctype p_c, ctype p_p) /*@*/ ;
142static bool ctbase_isFixedArray (/*@notnull@*/ ctbase p_c) /*@*/ ;
143
144/*@-macroundef@*/
145extern int cttable_lastIndex();
146# define cttable_lastIndex() (cttab.size - 1)
147/*@=macroundef@*/
148
28bf4b0b 149typedef struct
885824d3 150{
151 ctype rval;
28bf4b0b 152 /*@only@*/ uentryList params;
885824d3 153} *cfcn;
154
28bf4b0b 155typedef struct
885824d3 156{
157 cstring name;
158 uentryList fields;
159} *tsu;
160
28bf4b0b 161typedef struct
885824d3 162{
163 ctype a;
164 ctype b;
165 bool isExplicit;
166} *tconj;
167
28bf4b0b 168typedef struct
885824d3 169{
170 cstring tag;
171 enumNameList members;
172} *tenum;
173
28bf4b0b 174typedef struct
885824d3 175{
176 ctype base;
37ae0b5e 177 size_t size;
885824d3 178} *tfixed;
179
28bf4b0b 180typedef union
885824d3 181{
182 cprim prim; /* primitive */
183 typeId tid; /* abstract, user */
184 ctype base; /* ptr, array */
185 cfcn fcn; /* function */
186 tsu su; /* struct union */
187 tenum cenum; /* enum */
188 tconj conj; /* conj */
189 tfixed farray; /* fixed array */
190} uconts;
191
28bf4b0b 192struct s_ctbase
885824d3 193{
194 ctuid type;
195 uconts contents;
196} ;
197
198static /*@falsenull@*/ bool ctbase_isUA (ctbase p_c) /*@*/ ;
199static bool ctbase_isBaseUA(ctbase p_c) /*@*/ ;
200static typeId ctbase_typeBaseUid(ctbase p_c) /*@*/ ;
201static bool ctbase_isKind (/*@notnull@*/ ctbase p_c, ctuid p_kind) /*@*/ ;
202static bool ctbase_isKind2 (/*@notnull@*/ ctbase p_c, ctuid p_kind1, ctuid p_kind2) /*@*/ ;
203static /*@only@*/ /*@notnull@*/ ctbase
204 ctbase_getBaseType (/*@notnull@*/ ctbase p_c) /*@*/ ;
205
206static /*@falsenull@*/ bool ctbase_isFunction(ctbase p_c) /*@*/ ;
207
208/*@constant null ctbase ctbase_undefined; @*/
209# define ctbase_undefined ((ctbase)0)
210
211static /*@owned@*/ ctbase ctbase_bool = ctbase_undefined;
212static /*@owned@*/ ctbase ctbase_unknown = ctbase_undefined;
213
214static /*@falsenull@*/ bool ctbase_isDefined (ctbase c) /*@*/
215{
216 return ((c) != ctbase_undefined);
217}
218
219static /*@truenull@*/ bool ctbase_isUndefined (ctbase c)
220{
221 return ((c) == ctbase_undefined);
222}
223
224static ctkind ctype_getCtKind (ctype c)
225{
226 ctentry ce = ctype_getCtentry (c);
227
228 return ctentry_getKind (ce);
229}
230
231static bool ctbase_isUser (ctbase c)
232{
233 if (ctbase_isDefined (c))
234 {
235 return (ctbase_isKind (c, CT_USER));
236 }
237 else
238 {
239 return FALSE;
240 }
241}
242
243static bool ctbase_isEnum (ctbase c)
244{
245 if (ctbase_isDefined (c))
246 {
247 return (ctbase_isKind (c, CT_ENUM));
248 }
249 else
250 {
251 return FALSE;
252 }
253}
254
255static bool ctbase_isExpFcn (ctbase c)
256{
257 if (ctbase_isDefined (c))
258 {
259 return (c->type == CT_EXPFCN);
260 }
261 else
262 {
263 return FALSE;
264 }
265}
266
267static /*@falsenull@*/ bool ctbase_isConj (ctbase c)
268{
269 if (ctbase_isDefined (c))
270 {
271 return (c->type == CT_CONJ);
272 }
273 else
274 {
275 return FALSE;
276 }
277}
278
279static bool ctuid_isAP (ctuid c) /*@*/
280{
281 return (c == CT_ARRAY || c == CT_PTR);
282}
283
284static typeId ctbase_typeId (ctbase p_c);
285static /*@only@*/ cstring ctbase_dump (ctbase p_c);
86d93ed3 286static /*@only@*/ ctbase ctbase_undump (char **p_c) /*@requires maxRead(*p_c) >= 2 @*/;
885824d3 287static int ctbase_compare (ctbase p_c1, ctbase p_c2, bool p_strict);
288static bool ctbase_matchArg (ctbase p_c1, ctbase p_c2);
289static /*@notnull@*/ /*@only@*/ ctbase
290 ctbase_makeConj (ctype p_c1, ctype p_c2, bool p_isExplicit) /*@*/ ;
291static ctype ctbase_getConjA (/*@notnull@*/ ctbase p_c) /*@*/ ;
292static ctype ctbase_getConjB (/*@notnull@*/ ctbase p_c) /*@*/ ;
293static bool ctbase_isExplicitConj (/*@notnull@*/ ctbase p_c) /*@*/ ;
a0a162cd 294static bool ctbase_forceMatch (ctbase p_c1, ctbase p_c2) /*@modifies p_c1, p_c2@*/ ;
885824d3 295static /*@notnull@*/ /*@only@*/ ctbase ctbase_expectFunction (ctype p_c);
296static bool ctbase_isVoidPointer(/*@notnull@*/ /*@dependent@*/ ctbase p_c) /*@*/ ;
28bf4b0b 297static bool ctbase_isUnion (/*@notnull@*/ /*@temp@*/ ctbase p_c) /*@*/ ;
298static bool ctbase_isStruct (/*@notnull@*/ /*@temp@*/ ctbase p_c) /*@*/ ;
885824d3 299static /*@observer@*/ cstring ctbase_enumTag (/*@notnull@*/ ctbase p_ct) /*@*/ ;
300static /*@only@*/ cstring ctbase_unparseNotypes (ctbase p_c) /*@*/ ;
301
302static /*@out@*/ /*@notnull@*/ /*@only@*/ ctbase ctbase_new (void) /*@*/ ;
303static int nctbases = 0;
304
305static /*@notnull@*/ /*@only@*/
28bf4b0b 306 ctbase ctbase_makeLiveFunction (ctype p_b, /*@only@*/ uentryList p_p);
307
308static bool ctbase_isUnnamedSU (ctbase c)
309{
310 return (ctbase_isDefined (c)
311 && (ctbase_isStruct (c) || ctbase_isUnion (c))
312 && isFakeTag (c->contents.su->name));
313}
885824d3 314
315static /*@observer@*/ ctbase ctbase_realType (ctbase c)
316{
317 if (ctbase_isUA (c))
318 {
319 typeId uid = ctbase_typeId (c);
320
321 if (usymtab_isBoolType (uid))
322 {
323 return ctbase_getBool ();
324 }
325 else
326 {
327 ctbase ret = ctype_getCtbase
328 (uentry_getRealType (usymtab_getTypeEntry (ctbase_typeId (c))));
329
330 llassert (ret != ctbase_undefined);
331 return ret;
332 }
333 }
334 else
335 {
336 return c;
337 }
338}
339
340static bool
341ctbase_isVoidPointer (/*@dependent@*/ /*@notnull@*/ ctbase c)
342{
343 ctbase r = ctbase_realType (c);
344
345 return (ctbase_isKind (r, CT_PTR) &&
346 ctype_isVoid (r->contents.base));
347}
348
349static bool
350ctbase_isPointer (/*@notnull@*/ /*@dependent@*/ ctbase c)
351{
352 ctbase r = ctbase_realType (c);
353
354 return (ctbase_isKind (r, CT_PTR));
355}
356
357static bool
358ctbase_isEitherArray (/*@notnull@*/ ctbase c)
359{
360 ctbase r = ctbase_realType (c);
361
362 return (ctbase_isKind (r, CT_ARRAY)
363 || ctbase_isKind (r, CT_FIXEDARRAY));
364}
365
366static bool
367ctbase_isFixedArray (/*@notnull@*/ ctbase c)
368{
369 ctbase r = ctbase_realType (c);
370
371 return (ctbase_isKind (r, CT_FIXEDARRAY));
372}
373
374static bool
375ctbase_isStruct (/*@notnull@*/ ctbase c)
376{
377 ctbase r = ctbase_realType (c);
378
379 return (ctbase_isKind (r, CT_STRUCT));
380}
381
382static bool
28bf4b0b 383ctbase_isUnion (/*@notnull@*/ ctbase c)
885824d3 384{
385 ctbase r = ctbase_realType (c);
386
387 return (ctbase_isKind (r, CT_UNION));
388}
389
390/*
391** clean this up -> typeTable should store ctype
392*/
393
394static typeId
395ctbase_typeBaseUid (ctbase c)
396{
397 ctuid ct;
398
399 if (ctbase_isDefined (c))
400 {
401 ct = c->type;
402
403 if (ctuid_isAP (ct))
404 {
405 return ctbase_typeBaseUid (ctype_getCtbase (c->contents.base));
406 }
e5081f8c 407 else if (ct == CT_USER || ct == CT_ABST || ct == CT_NUMABST)
885824d3 408 {
409 return c->contents.tid;
410 }
411 else if (ct == CT_FIXEDARRAY)
412 {
413 return ctbase_typeBaseUid (ctype_getCtbase (c->contents.farray->base));
414 }
415 else
416 {
417 llcontbuglit ("ctbase_typeBaseUid: bad call");
418 return typeId_invalid;
419 }
420 }
421 return typeId_invalid;
422}
423
424static bool
425ctbase_isBaseUA (ctbase c)
426{
427 ctuid ct;
428
429 if (ctbase_isDefined (c))
430 {
431 ct = c->type;
432
433 if (ctuid_isAP (ct))
434 {
435 return ctbase_isBaseUA (ctype_getCtbase (c->contents.base));
436 }
437 else if (ct == CT_FIXEDARRAY)
438 {
439 return ctbase_isBaseUA (ctype_getCtbase (c->contents.farray->base));
440 }
441 else
e5081f8c 442 return (ct == CT_USER || ct == CT_ABST || ct == CT_NUMABST);
885824d3 443 }
444 return FALSE;
445}
446
447static typeId
448ctbase_typeId (ctbase c)
449{
450 if (ctbase_isUA (c))
451 {
452 return c->contents.tid;
453 }
454 else
455 {
28bf4b0b 456 if (ctbase_isConj (c))
457 {
458 return ctbase_typeId (ctype_getCtbase (ctbase_getConjA (c)));
459 }
460 else
461 {
462 llcontbug (message ("ctbase_typeId: bad call: %q", ctbase_unparse (c)));
463 return typeId_invalid;
464 }
885824d3 465 }
466}
467
468static /*@only@*/ cstring
469ctbase_unparse (ctbase c)
470{
471 if (ctbase_isUndefined (c)) {
472 return cstring_makeLiteral ("<<undef>>");
473 }
474
475 switch (c->type)
476 {
477 case CT_UNKNOWN:
478 return cstring_makeLiteral ("?");
479 case CT_BOOL:
480 return cstring_copy (context_printBoolName ());
481 case CT_PRIM:
482 return (cprim_unparse (c->contents.prim));
483 case CT_USER:
885824d3 484 case CT_ABST:
e5081f8c 485 case CT_NUMABST:
885824d3 486 return (usymtab_getTypeEntryName (c->contents.tid));
487 case CT_EXPFCN:
488 return (message ("<expf: %t>", c->contents.base));
489 case CT_PTR:
490 /* no spaces for multiple pointers */
491
492 if (ctype_isPointer (c->contents.base))
493 {
494 return (cstring_appendChar (cstring_copy (ctype_unparse (c->contents.base)), '*'));
495 }
496 else
497 {
498 return (message ("%t *", c->contents.base));
499 }
500 case CT_FIXEDARRAY:
077d4458 501 return (message ("%t [%d]",
502 c->contents.farray->base,
885824d3 503 (int) c->contents.farray->size));
504 case CT_ARRAY:
505 return (message ("%t []", c->contents.base));
506 case CT_FCN:
507 return (message ("[function (%q) returns %t]",
508 uentryList_unparseParams (c->contents.fcn->params),
509 c->contents.fcn->rval));
510 case CT_STRUCT:
511 if (cstring_isDefined (c->contents.su->name) &&
512 !cstring_isEmpty (c->contents.su->name) &&
513 !isFakeTag (c->contents.su->name))
514 {
515 return (message ("struct %s", c->contents.su->name));
516 }
517 else
518 {
28bf4b0b 519 return (message ("struct { %q }",
520 uentryList_unparseAbbrev (c->contents.su->fields)));
885824d3 521 }
522 case CT_UNION:
523 if (cstring_isDefined (c->contents.su->name) &&
524 !cstring_isEmpty (c->contents.su->name) &&
525 !isFakeTag (c->contents.su->name))
526 {
527 return (message ("union %s", c->contents.su->name));
528 }
529 else
530 {
531 return (message ("union { %q }",
532 uentryList_unparseAbbrev (c->contents.su->fields)));
533 }
534 case CT_ENUM:
535 if (isFakeTag (c->contents.cenum->tag))
536 {
537 return (message ("enum { %q }",
538 enumNameList_unparseBrief (c->contents.cenum->members)));
539 }
540 else
541 {
542 return (message ("enum %s { %q }",
543 c->contents.cenum->tag,
544 enumNameList_unparseBrief (c->contents.cenum->members)));
545 }
546 case CT_CONJ:
d5047b91 547 if (ctbase_isAnytype (c))
548 {
549 return (cstring_makeLiteral ("<any>"));
550 }
551 else if (c->contents.conj->isExplicit || context_getFlag (FLG_SHOWALLCONJS))
885824d3 552 {
553 if (!ctype_isSimple (c->contents.conj->a) ||
554 !ctype_isSimple (c->contents.conj->b))
555 {
556 return (message ("<%t> | <%t>", c->contents.conj->a, c->contents.conj->b));
557 }
558 else
559 {
560 return (message ("%t | %t", c->contents.conj->a, c->contents.conj->b));
561 }
562 }
563 else
564 {
565 return (cstring_copy (ctype_unparse (c->contents.conj->a)));
566 }
567 BADDEFAULT;
568 }
569 BADEXIT;
570}
571
572static /*@only@*/ cstring
573 ctbase_unparseDeep (ctbase c)
574{
575 if (ctbase_isUndefined (c))
576 {
577 return cstring_makeLiteral ("<<undef>>");
578 }
579
580 switch (c->type)
581 {
582 case CT_UNKNOWN:
583 return cstring_makeLiteral ("?");
584 case CT_BOOL:
585 return cstring_copy (context_printBoolName ());
586 case CT_PRIM:
587 return (cprim_unparse (c->contents.prim));
588 case CT_ENUM:
589 if (cstring_isNonEmpty (c->contents.cenum->tag))
590 {
591 return (message ("enum %s { %q }",
592 c->contents.cenum->tag,
593 enumNameList_unparse (c->contents.cenum->members)));
594 }
595 else
596 {
597 return (message ("enum { %q }",
598 enumNameList_unparse (c->contents.cenum->members)));
599 }
600 case CT_USER:
885824d3 601 case CT_ABST:
e5081f8c 602 case CT_NUMABST:
885824d3 603 return (usymtab_getTypeEntryName (c->contents.tid));
604 case CT_EXPFCN:
605 return (message ("<expf: %t>", c->contents.base));
606 case CT_PTR:
607 return (message ("%t *", c->contents.base));
608 case CT_FIXEDARRAY:
609 return (message ("%t [%d]", c->contents.farray->base,
610 (int) c->contents.farray->size));
611 case CT_ARRAY:
612 return (message ("%t []", c->contents.base));
613 case CT_FCN:
614 return (message ("[function (%q) returns %t]",
615 uentryList_unparse (c->contents.fcn->params),
616 c->contents.fcn->rval));
617 case CT_STRUCT:
618 return (message ("struct %s { ... } ", c->contents.su->name));
619 case CT_UNION:
620 return (message ("union %s { ... }", c->contents.su->name));
621 case CT_CONJ:
d5047b91 622 if (ctbase_isAnytype (c))
623 {
624 return (cstring_makeLiteral ("<any>"));
625 }
626 else
627 {
628 return (message ("%t", c->contents.conj->a));
629 }
885824d3 630 BADDEFAULT;
631 }
632 BADEXIT;
633}
634
635static /*@only@*/ cstring
636ctbase_unparseNotypes (ctbase c)
637{
638 llassert (ctbase_isDefined (c));
639
640 switch (c->type)
641 {
642 case CT_UNKNOWN:
643 return cstring_makeLiteral ("?");
644 case CT_BOOL:
645 return cstring_copy (context_printBoolName ());
646 case CT_PRIM:
647 return (cprim_unparse (c->contents.prim));
648 case CT_ENUM:
649 if (typeId_isInvalid (c->contents.tid))
650 {
651 return cstring_makeLiteral ("enum");
652 }
653 else
654 {
655 return (message ("T#%d", c->contents.tid));
656 }
657 case CT_USER:
658 return (message ("uT#%d", c->contents.tid));
659 case CT_ABST:
660 return (message ("aT#%d", c->contents.tid));
e5081f8c 661 case CT_NUMABST:
662 return (message ("nT#%d", c->contents.tid));
885824d3 663 case CT_EXPFCN:
664 return (message ("<expf: %q >", ctbase_unparseNotypes (ctype_getCtbase (c->contents.base))));
665 case CT_PTR:
666 return (message ("%q *", ctbase_unparseNotypes (ctype_getCtbase (c->contents.base))));
667 case CT_ARRAY:
668 return (message ("%q []", ctbase_unparseNotypes (ctype_getCtbase (c->contents.base))));
669 case CT_FCN:
670 return (message ("[function (%d) returns %q]", uentryList_size (c->contents.fcn->params),
671 ctbase_unparseNotypes (ctype_getCtbase (c->contents.fcn->rval))));
672 case CT_STRUCT:
673 return (message ("struct %s", c->contents.su->name));
674 case CT_UNION:
675 return (message ("union %s", c->contents.su->name));
676 case CT_ENUMLIST:
677 return (message ("[enumlist]"));
678 case CT_CONJ:
d5047b91 679 if (ctbase_isAnytype (c))
680 {
681 return (cstring_makeLiteral ("<any>"));
682 }
683 else
684 {
685 return (message ("%q/%q",
686 ctbase_unparseNotypes (ctype_getCtbase (c->contents.conj->a)),
687 ctbase_unparseNotypes (ctype_getCtbase (c->contents.conj->b))));
688 }
885824d3 689 BADDEFAULT;
690 }
691 BADEXIT;
692}
693
694static /*@only@*/ cstring
695ctbase_unparseDeclaration (ctbase c, /*@only@*/ cstring name) /*@*/
696{
697 if (ctbase_isUndefined (c))
698 {
699 return name;
700 }
701
702 switch (c->type)
703 {
704 case CT_UNKNOWN:
705 return (message ("? %q", name));
706 case CT_BOOL:
707 return (message ("%s %q", context_printBoolName (), name));
708 case CT_PRIM:
709 return (message ("%q %q", cprim_unparse (c->contents.prim), name));
710 case CT_USER:
711 case CT_ABST:
e5081f8c 712 case CT_NUMABST:
885824d3 713 return (message ("%q %q", usymtab_getTypeEntryName (c->contents.tid), name));
714 case CT_EXPFCN:
715 llcontbuglit ("ctbase_unparseDeclaration: expfcn");
716 return name;
717 case CT_PTR:
718 if (ctype_isFunction (c->contents.base))
719 {
720 return ctbase_unparseDeclaration (ctype_getCtbase (c->contents.base), name);
721 }
722 else
723 {
724 cstring s = cstring_prependChar ('*', name);
725 cstring ret = ctbase_unparseDeclaration (ctype_getCtbase (c->contents.base), s);
726 cstring_free (name);
727 return (ret);
728 }
729 case CT_FIXEDARRAY:
730 return (message ("%q[%d]",
731 ctbase_unparseDeclaration (ctype_getCtbase (c->contents.farray->base), name),
732 (int) c->contents.farray->size));
733 case CT_ARRAY:
734 return (message ("%q[]",
735 ctbase_unparseDeclaration (ctype_getCtbase (c->contents.base), name)));
736 case CT_FCN:
737 {
738 cstring s = message ("%q(%q)", name,
739 uentryList_unparseParams (c->contents.fcn->params));
740
741 return (ctbase_unparseDeclaration
742 (ctype_getCtbase (c->contents.fcn->rval), s));
743 }
744 case CT_STRUCT:
745 if (cstring_isDefined (c->contents.su->name) &&
746 !cstring_isEmpty (c->contents.su->name) &&
747 !isFakeTag (c->contents.su->name))
748 {
749 return (message ("struct %s %q", c->contents.su->name, name));
750 }
751 else
752 {
753 return (message ("struct { %q } %q",
754 uentryList_unparseAbbrev (c->contents.su->fields),
755 name));
756 }
757 case CT_UNION:
758 if (cstring_isDefined (c->contents.su->name) &&
759 !cstring_isEmpty (c->contents.su->name) &&
760 !isFakeTag (c->contents.su->name))
761 {
762 return (message ("union %s %q", c->contents.su->name, name));
763 }
764 else
765 {
766 return (message ("union { %q } %q",
767 uentryList_unparseAbbrev (c->contents.su->fields),
768 name));
769 }
770 case CT_ENUM:
771 if (isFakeTag (c->contents.cenum->tag))
772 {
773 return (message ("enum { %q } %q",
774 enumNameList_unparseBrief (c->contents.cenum->members),
775 name));
776 }
777 else
778 {
779 return (message ("enum %s { %q } %q",
780 c->contents.cenum->tag,
781 enumNameList_unparseBrief (c->contents.cenum->members),
782 name));
783 }
d5047b91 784 case CT_CONJ:
785 if (ctbase_isAnytype (c))
786 {
787 return (message ("<any> %q", name));
788 }
789 else if (c->contents.conj->isExplicit || context_getFlag (FLG_SHOWALLCONJS))
885824d3 790 {
791 if (!ctype_isSimple (c->contents.conj->a) ||
792 !ctype_isSimple (c->contents.conj->b))
793 {
794 cstring name1 = cstring_copy (name);
795
796 return
797 (message
798 ("<%q> | <%q>",
799 ctbase_unparseDeclaration
800 (ctype_getCtbase (c->contents.conj->a), name1),
801 ctbase_unparseDeclaration
802 (ctype_getCtbase (c->contents.conj->b), name)));
803 }
804 else
805 {
806 cstring s1 = ctbase_unparseDeclaration (ctype_getCtbase (c->contents.conj->a),
807 cstring_copy (name));
808 return
809 (message ("%q | %q", s1,
810 ctbase_unparseDeclaration (ctype_getCtbase (c->contents.conj->b),
811 name)));
812 }
813 }
814 else
815 {
816 cstring_free (name);
817 return (cstring_copy (ctype_unparse (c->contents.conj->a)));
818 }
819 BADDEFAULT;
820 }
821 BADEXIT;
822}
823
86d93ed3 824static ctbase ctbase_undump (d_char *c) /*@requires maxRead(*c) >= 2 @*/
885824d3 825{
826 ctbase res;
827 char p = **c;
828
829 (*c)++;
830
831 switch (p)
832 {
833 case '?':
834 return (ctbase_undefined);
835 case 'u':
836 return (ctbase_createUnknown ());
837 case 'b':
838 return (ctbase_createBool ());
839 case 'p':
28bf4b0b 840 res = ctbase_createPrim (cprim_fromInt (reader_getInt (c)));
841 reader_checkChar (c, '|');
885824d3 842 return res;
843 case 's':
28bf4b0b 844 res = ctbase_createUser (typeId_fromInt (reader_getInt (c)));
845 reader_checkChar (c, '|');
885824d3 846 return res;
847 case 'a':
28bf4b0b 848 res = ctbase_createAbstract (typeId_fromInt (reader_getInt (c)));
849 reader_checkChar (c, '|');
885824d3 850 return res;
e5081f8c 851 case 'n':
852 res = ctbase_createNumAbstract (typeId_fromInt (reader_getInt (c)));
853 reader_checkChar (c, '|');
854 return res;
885824d3 855 case 't':
856 res = ctbase_makePointer (ctype_undump (c));
28bf4b0b 857 reader_checkChar (c, '|');
885824d3 858 return res;
859 case 'y':
860 res = ctbase_makeArray (ctype_undump (c));
28bf4b0b 861 reader_checkChar (c, '|');
885824d3 862 return res;
863 case 'F':
864 {
865 ctype ct = ctype_undump (c);
37ae0b5e 866 size_t size;
885824d3 867
28bf4b0b 868 reader_checkChar (c, '/');
37ae0b5e 869 size = size_fromInt (reader_getInt (c));
28bf4b0b 870 reader_checkChar (c, '|');
885824d3 871 return (ctbase_makeFixedArray (ct, size));
872 }
873 case 'f':
874 {
875 ctype ct;
876 char *lp = strchr (*c, '(');
877
878 llassertfatal (lp != NULL);
879
880 *lp = '\0';
881 ct = ctype_undump (c);
882 *c = lp + 1;
883
884 return (ctbase_makeLiveFunction (ct, uentryList_undump (c)));
885 }
886 case 'S':
887 {
888 uentryList fields;
889 ctbase ctb;
890 char *sname;
891 char *lc = strchr (*c, '{');
892
893 llassert (lc != NULL);
894 *lc = '\0';
895
896 sname = mstring_copy (*c);
897
898 *c = lc + 1;
899
900 if (*sname == '!')
901 {
902 unsigned int i;
903
904 i = (unsigned) atoi (sname + 1);
905
906 setTagNo (i);
907 }
908
909 fields = uentryList_undumpFields (c, g_currentloc);
910
911 ctb = ctbase_createStruct (cstring_fromCharsO (sname), fields);
912 return ctb;
913 }
914 case 'U':
915 {
916 char *sname;
917 char *lc = strchr (*c, '{');
918
919 llassert (lc != NULL);
920
921 *lc = '\0';
922 sname = mstring_copy (*c);
923 llassert (sname != NULL);
924
925 *c = lc + 1;
926
927 if (*sname == '!')
928 {
929 unsigned int i;
930
931 i = (unsigned) atoi (sname + 1);
932 setTagNo (i);
933 }
934
935 return (ctbase_createUnion (cstring_fromCharsO (sname),
936 uentryList_undumpFields (c, g_currentloc)));
937 }
938 case 'e':
939 {
940 ctbase ret;
941 char *sname;
942 char *lc = strchr (*c, '{');
943
944 llassert (lc != NULL);
945
946 *lc = '\0';
947 sname = mstring_copy (*c);
948 *c = lc + 1;
949
950 if (*sname == '!')
951 {
952 unsigned int i;
953
954 i = (unsigned) atoi (sname + 1);
955 setTagNo (i);
956 }
957
958 ret = ctbase_createEnum (cstring_fromCharsO (sname),
959 enumNameList_undump (c));
960 return ret;
961 }
962 case 'C':
963 {
964 bool isExplicit;
965 ctype c1, c2;
966
28bf4b0b 967 isExplicit = bool_fromInt (reader_getInt (c));
968 reader_checkChar (c, '.');
885824d3 969 c1 = ctype_undump (c);
28bf4b0b 970 reader_checkChar (c, '/');
885824d3 971 c2 = ctype_undump (c);
28bf4b0b 972 reader_checkChar (c, '|');
885824d3 973
974 return (ctbase_makeConj (c1, c2, isExplicit));
975 }
976
977 default:
978 (*c)--;
979 llerror (FLG_SYNTAX,
980 message ("Bad Library line (type): %s", cstring_fromChars (*c)));
981
86d93ed3 982 /*drl bee: pbr*/ while (**c != '\0')
885824d3 983 {
984 (*c)++;
985 }
986
987 return ctbase_createUnknown ();
988 }
989}
990
991/* first letter of c encodes type: */
992/* u unknown */
993/* b bool */
994/* p prim */
995/* e enum */
996/* l enumList */
997/* s uSer */
998/* a abstract */
999/* t poinTer */
1000/* y arraY */
1001/* F Fixed array */
1002/* f function */
1003/* S structure */
1004/* U union */
1005/* C conj */
1006
1007static /*@only@*/ cstring
1008ctbase_dump (ctbase c)
1009{
1010 if (!ctbase_isDefined (c))
1011 {
1012 return cstring_makeLiteral ("?");
1013 }
1014
1015 switch (c->type)
1016 {
1017 case CT_UNKNOWN:
1018 return cstring_makeLiteral ("u");
1019 case CT_BOOL:
1020 return cstring_makeLiteral ("b");
1021 case CT_PRIM:
1022 return (message ("p%d|", c->contents.prim));
1023 case CT_USER:
1024 return (message ("s%d|",
1025 usymtab_convertId (c->contents.tid)));
1026 case CT_ABST:
1027 return (message ("a%d|", usymtab_convertId (c->contents.tid)));
e5081f8c 1028 case CT_NUMABST:
1029 return (message ("n%d|", usymtab_convertId (c->contents.tid)));
885824d3 1030 case CT_PTR:
1031 return (message ("t%q|", ctype_dump (c->contents.base)));
1032 case CT_ARRAY:
1033 return (message ("y%q|", ctype_dump (c->contents.base)));
1034 case CT_FIXEDARRAY:
1035 return (message ("F%q/%d|",
1036 ctype_dump (c->contents.farray->base),
1037 (int) c->contents.farray->size));
1038 case CT_FCN:
28bf4b0b 1039 DPRINTF (("Dump function: %s", ctbase_unparse (c)));
885824d3 1040 return (message ("f%q (%q)", ctype_dump (c->contents.fcn->rval),
1041 uentryList_dumpParams (c->contents.fcn->params)));
1042 case CT_STRUCT:
1043 return (message ("S%s{%q}", c->contents.su->name,
1044 uentryList_dumpFields (c->contents.su->fields)));
1045 case CT_UNION:
1046 return (message ("U%s{%q}", c->contents.su->name,
1047 uentryList_dumpFields (c->contents.su->fields)));
1048 case CT_ENUM:
1049 {
1050 cstring s;
1051
1052 if (cstring_isNonEmpty (c->contents.cenum->tag))
1053 {
1054 s = message ("e%s{%q}",
1055 c->contents.cenum->tag,
1056 enumNameList_dump (c->contents.cenum->members));
1057 }
1058 else
1059 {
1060 s = message ("e{%q}",
1061 enumNameList_dump (c->contents.cenum->members));
1062 }
1063 return (s);
1064 }
1065 case CT_CONJ:
1066 return (message ("C%d.%q/%q|",
1067 bool_toInt (c->contents.conj->isExplicit),
1068 ctype_dump (c->contents.conj->a),
1069 ctype_dump (c->contents.conj->b)));
1070 case CT_EXPFCN:
1071 /* should clean them up! */
1072 return (cstring_makeLiteral ("?"));
1073 case CT_ENUMLIST:
1074 llcontbug (message ("Cannot dump: %q", ctbase_unparse (c)));
1075 return (message ("u"));
1076 BADDEFAULT;
1077 }
1078
1079 BADEXIT;
1080}
1081
1082static /*@only@*/ ctbase
1083ctbase_copy (/*@notnull@*/ ctbase c)
1084{
1085 switch (c->type)
1086 {
1087 case CT_UNKNOWN:
1088 return (ctbase_createUnknown ());
1089 case CT_BOOL:
1090 return (ctbase_createBool ());
1091 case CT_ENUM:
1092 return (ctbase_createEnum (cstring_copy (c->contents.cenum->tag),
1093 enumNameList_copy (c->contents.cenum->members)));
1094 case CT_PRIM:
1095 return (ctbase_createPrim (c->contents.prim));
1096 case CT_USER:
1097 return (ctbase_createUser (c->contents.tid));
1098 case CT_ABST:
1099 return (ctbase_createAbstract (c->contents.tid));
e5081f8c 1100 case CT_NUMABST:
1101 return (ctbase_createNumAbstract (c->contents.tid));
885824d3 1102 case CT_EXPFCN:
1103 return (ctbase_expectFunction (c->contents.base));
1104 case CT_PTR:
1105 return (ctbase_makePointer (c->contents.base));
1106 case CT_ARRAY:
1107 return (ctbase_makeArray (c->contents.base));
1108 case CT_FCN:
1109 return (ctbase_makeLiveFunction (c->contents.fcn->rval,
1110 uentryList_copy (c->contents.fcn->params)));
1111 case CT_STRUCT:
1112 return (ctbase_createStruct (cstring_copy (c->contents.su->name),
1113 uentryList_copy (c->contents.su->fields)));
1114 case CT_UNION:
1115 return (ctbase_createUnion (cstring_copy (c->contents.su->name),
1116 uentryList_copy (c->contents.su->fields)));
1117 case CT_CONJ:
1118 /*@i@*/ return (c); /* not a real copy for conj's */
1119 default:
1120 llbug (message ("ctbase_copy: %q", ctbase_unparse (c)));
1121 }
1122
1123 BADEXIT;
1124}
1125
1126static enumNameList
1127ctbase_elist (ctbase c)
1128{
1129 llassert (ctbase_isDefined (c));
1130 llassert (c->type == CT_ENUM);
1131
1132 return (c->contents.cenum->members);
1133}
1134
1135static void
1136ctbase_free (/*@only@*/ ctbase c)
1137{
1138 if (c == ctbase_bool || c == ctbase_unknown)
1139 {
1140 /*@-mustfree@*/ return; /*@=mustfree@*/
1141 }
1142
1143 --nctbases;
1144
1145
1146 if (ctbase_isDefined (c))
1147 {
1148 switch (c->type)
1149 {
1150 case CT_UNKNOWN:
1151 sfree (c);
1152 break;
1153 case CT_PRIM:
1154 sfree (c);
1155 break;
1156 case CT_ENUM:
1157 sfree (c);
1158 break;
1159 case CT_ENUMLIST:
1160 /* sfree list? */
1161 sfree (c);
1162 break;
1163 case CT_USER:
885824d3 1164 case CT_ABST:
e5081f8c 1165 case CT_NUMABST:
885824d3 1166 sfree (c);
1167 break;
1168 case CT_PTR:
1169 case CT_ARRAY:
1170 sfree (c);
1171 break;
1172 case CT_FCN:
28bf4b0b 1173 /*@i32@*/ /* uentryList_free (c->contents.fcn->params); */
885824d3 1174 sfree (c);
1175 break;
1176 case CT_STRUCT:
1177 case CT_UNION:
1178 cstring_free (c->contents.su->name);
1179 uentryList_free (c->contents.su->fields);
1180 sfree (c);
1181 break;
1182 case CT_CONJ:
1183 /* Don't bree conj's, */
1184 break;
1185 default:
1186 sfree (c);
1187 break;
1188 }
1189 }
1190}
1191
1192/*
1193** c should be * <unknown>
1194*/
1195
1196static /*@only@*/ ctbase
1197ctbase_expectFunction (ctype c)
1198{
1199 ctbase f = ctbase_new ();
1200
1201 f->type = CT_EXPFCN;
1202 f->contents.base = c;
1203
1204 return (f);
1205}
1206
e8b84478 1207static bool
abd7f895 1208ctbase_isExpectFunction (/*@notnull@*/ ctbase ct) /*@*/
e8b84478 1209{
1210 return (ct->type == CT_EXPFCN);
1211}
1212
1213static ctype
abd7f895 1214ctbase_getExpectFunction (/*@notnull@*/ ctbase ct)
e8b84478 1215{
1216 llassert (ctbase_isExpectFunction (ct));
1217 return ct->contents.base;
1218}
1219
885824d3 1220static bool
a0a162cd 1221ctbase_genMatch (ctbase c1, ctbase c2, bool force, bool arg, bool def, bool deep)
885824d3 1222{
1223 ctuid c1tid, c2tid;
1224
1225 /* undefined types never match */
1226
1227 if (ctbase_isUndefined (c1) || ctbase_isUndefined (c2))
1228 return FALSE;
1229
1230 /* abstract types match user types of same name */
1231
1232 c1 = ctbase_realType (c1);
1233 c2 = ctbase_realType (c2);
1234
a0a162cd 1235 DPRINTF (("Matching: %s / %s", ctbase_unparse (c1),
1236 ctbase_unparse (c2)));
1237
885824d3 1238 c1tid = c1->type;
1239 c2tid = c2->type;
1240
1241 if (c1tid == CT_CONJ)
1242 {
1243 return (ctbase_genMatch (ctype_getCtbase (c1->contents.conj->a), c2,
a0a162cd 1244 force, arg, def, deep)
885824d3 1245 || ctbase_genMatch (ctype_getCtbase (c1->contents.conj->b), c2,
a0a162cd 1246 force, arg, def, deep));
885824d3 1247 }
1248
1249 if (c2tid == CT_CONJ)
1250 {
1251 return (ctbase_genMatch (c1, ctype_getCtbase (c2->contents.conj->a),
a0a162cd 1252 force, arg, def, deep)
885824d3 1253 || ctbase_genMatch (c1, ctype_getCtbase (c2->contents.conj->b),
a0a162cd 1254 force, arg, def, deep));
885824d3 1255 }
1256
1257 /*
1258 ** if the types don't match, there are some special cases...
1259 */
1260
1261 if (c1tid != c2tid)
1262 {
1263 /* unknowns match anything */
1264
1265 if (c1tid == CT_UNKNOWN || c2tid == CT_UNKNOWN)
1266 {
1267 return TRUE;
1268 }
1269
1270 if (c1tid == CT_FIXEDARRAY
1271 && (c2tid == CT_ARRAY || (!def && c2tid == CT_PTR)))
1272 {
1273 if (ctype_isVoid (c2->contents.base))
1274 {
1275 return (context_getFlag (FLG_ABSTVOIDP) ||
1276 (!(ctype_isRealAbstract (c1->contents.farray->base)) &&
1277 !(ctype_isRealAbstract (c2->contents.base))));
1278 }
1279
1280 return (ctbase_genMatch (ctype_getCtbase (c1->contents.farray->base),
1281 ctype_getCtbase (c2->contents.base),
a0a162cd 1282 force, arg, def, deep));
885824d3 1283 }
1284
1285
1286 if (c2tid == CT_FIXEDARRAY
1287 && (c1tid == CT_ARRAY || (!def && c1tid == CT_PTR)))
1288 {
1289 if (ctype_isVoid (c1->contents.base))
1290 {
1291 return (context_getFlag (FLG_ABSTVOIDP) ||
1292 (!(ctype_isRealAbstract (c2->contents.farray->base)) &&
1293 !(ctype_isRealAbstract (c1->contents.base))));
1294 }
1295
1296 return (ctbase_genMatch (ctype_getCtbase (c1->contents.base),
1297 ctype_getCtbase (c2->contents.farray->base),
a0a162cd 1298 force, arg, def, deep));
885824d3 1299 }
1300
a0a162cd 1301 /* evs 2000-07-25: Bool's may match user/abstract types */
1302
885824d3 1303 if ((c1tid == CT_BOOL
1304 && (c2tid == CT_PRIM && cprim_isInt (c2->contents.prim))) ||
1305 (c2tid == CT_BOOL
1306 && (c1tid == CT_PRIM && cprim_isInt (c1->contents.prim))))
1307 {
1308 return (context_msgBoolInt ());
1309 }
1310
e5081f8c 1311 if ((c1tid == CT_BOOL && (ctuid_isAnyUserType (c2tid)))) {
a0a162cd 1312 ctype t2c = c2->contents.base;
a0a162cd 1313 return (ctype_isBool (t2c));
1314 }
1315
e5081f8c 1316 if ((c2tid == CT_BOOL && (ctuid_isAnyUserType (c1tid)))) {
a0a162cd 1317 ctype t1c = c1->contents.base;
1318
1319 return (ctype_isBool (t1c));
1320 }
1321
885824d3 1322 if ((c1tid == CT_ENUM
1323 && (c2tid == CT_PRIM && cprim_isInt (c2->contents.prim))) ||
1324 (c2tid == CT_ENUM
1325 && (c1tid == CT_PRIM && cprim_isInt (c1->contents.prim))))
1326 {
1327 return (context_msgEnumInt ());
1328 }
1329
1330 /*
1331 ** arrays and pointers...yuk!
1332 **
1333 ** Considered equivalent except in definitions.
1334 ** (e.g., function parameters are equivalent)
1335 **
1336 */
1337
1338 if (!def)
1339 {
1340 if (ctuid_isAP (c1tid) && ctuid_isAP (c2tid))
1341 {
1342 c2tid = c1tid;
1343 }
1344 }
1345
1346 /*
1347 ** Function pointers can be removed.
1348 **
1349 ** [function ..] is equivalent to [function ..] *
1350 */
1351
1352 if (c1tid == CT_PTR && c2tid == CT_FCN)
1353 {
1354 if (ctype_isFunction (ctype_realType (c1->contents.base)))
1355 {
1356 c1 = ctbase_realType (ctype_getCtbaseSafe (c1->contents.base));
1357 c1tid = c1->type;
1358 }
1359 }
1360
1361 if (c2tid == CT_PTR && c1tid == CT_FCN)
1362 {
1363 if (ctype_isFunction (ctype_realType (c2->contents.base)))
1364 {
1365 c2 = ctbase_realType (ctype_getCtbaseSafe (c2->contents.base));
1366 c2tid = c2->type;
1367 }
1368 }
1369
1370 /*
1371 ** we allow forward declarations to structures like,
1372 **
1373 ** typedef struct _t *t;
1374 **
1375 ** to allow,
1376 ** struct _t * to match t
1377 */
1378
1379 if (context_getFlag (FLG_FORWARDDECL))
1380 {
e5081f8c 1381 if (ctuid_isAnyUserType (c1tid))
885824d3 1382 {
1383 if (ctuid_isAP (c2tid))
1384 {
1385 ctype ts = c2->contents.base;
1386
1387 if (ctype_isUA (ts))
1388 {
1389 typeId ttid = ctype_typeId (ts);
1390 typeId ctid = c1->contents.tid ;
1391
1392 if (usymtab_matchForwardStruct (ctid, ttid))
1393 {
1394 return TRUE;
1395 }
1396 }
1397 }
1398 }
1399
e5081f8c 1400 if (ctuid_isAnyUserType (c2tid))
885824d3 1401 {
1402 if (ctuid_isAP (c1tid))
1403 {
1404 ctype ts = c1->contents.base;
1405
1406 if (ctype_isUA (ts))
1407 {
1408 typeId ttid = ctype_typeId (ts);
1409 typeId ctid = c2->contents.tid ;
1410
1411 if (usymtab_matchForwardStruct (ctid, ttid))
1412 {
1413 return TRUE;
1414 }
1415 }
1416 }
1417 }
1418 }
1419 }
1420
1421 if (c1tid != c2tid)
1422 return FALSE;
1423
1424 switch (c1tid)
1425 {
1426 case CT_UNKNOWN:
1427 return (TRUE);
1428 case CT_PRIM:
a0a162cd 1429 if (deep) {
1430 return (cprim_closeEnoughDeep (c1->contents.prim, c2->contents.prim));
1431 } else {
1432 return (cprim_closeEnough (c1->contents.prim, c2->contents.prim));
1433 }
885824d3 1434 case CT_BOOL:
1435 return (TRUE);
1436 case CT_ABST:
e5081f8c 1437 case CT_NUMABST:
885824d3 1438 case CT_USER:
1439 return (typeId_equal (c1->contents.tid, c2->contents.tid));
1440 case CT_ENUM:
1441 return (cstring_equal (c1->contents.cenum->tag, c2->contents.cenum->tag));
1442 case CT_PTR:
1443 if (ctype_isVoid (c1->contents.base)
1444 || (ctype_isVoid (c2->contents.base)))
1445 {
1446 if (ctype_isFunction (ctype_realType (c1->contents.base))
1447 || ctype_isFunction (ctype_realType (c2->contents.base)))
1448 {
1449 return (!context_getFlag (FLG_CASTFCNPTR));
1450 }
1451 else
1452 {
1453 return (context_getFlag (FLG_ABSTVOIDP) ||
1454 (!(ctype_isRealAbstract (c1->contents.base)) &&
1455 !(ctype_isRealAbstract (c2->contents.base))));
1456 }
1457 }
1458 else
1459 {
1460 /* Only allow one implicit function pointer. */
1461
1462 if (!bool_equal (ctype_isRealPointer (c1->contents.base),
1463 ctype_isRealPointer (c2->contents.base))
1464 && (ctype_isRealFunction (c1->contents.base)
1465 || ctype_isRealFunction (c2->contents.base)))
1466 {
1467 return FALSE;
1468 }
a0a162cd 1469
885824d3 1470 return (ctype_genMatch (c1->contents.base,
a0a162cd 1471 c2->contents.base, force, arg, def, TRUE));
885824d3 1472 }
1473 case CT_FIXEDARRAY:
1474 if (ctype_isVoid (c1->contents.farray->base)
1475 || ctype_isVoid (c2->contents.farray->base))
1476 return TRUE;
1477 return (ctype_genMatch (c1->contents.farray->base,
1478 c2->contents.farray->base,
a0a162cd 1479 force, arg, def, deep));
885824d3 1480 case CT_ARRAY:
1481 if (ctype_isVoid (c1->contents.base) || ctype_isVoid (c2->contents.base))
1482 return TRUE;
a0a162cd 1483 return (ctype_genMatch (c1->contents.base, c2->contents.base, force, arg, def, TRUE));
885824d3 1484 case CT_FCN:
1485 return (ctype_genMatch (c1->contents.fcn->rval,
1486 c2->contents.fcn->rval,
a0a162cd 1487 force, arg, def, TRUE)
885824d3 1488 && uentryList_matchParams (c1->contents.fcn->params,
1489 c2->contents.fcn->params,
1490 force, TRUE));
1491 case CT_STRUCT:
1492 case CT_UNION:
a0a162cd 1493 DPRINTF (("Struct: %s / %s",
1494 c1->contents.su->name,
1495 c2->contents.su->name));
1496
28bf4b0b 1497 if (isFakeTag (c1->contents.su->name)
1498 && isFakeTag (c2->contents.su->name))
885824d3 1499 {
28bf4b0b 1500 /* Both fake tags, check structure */
1501 if (cstring_equal (c1->contents.su->name, c2->contents.su->name))
1502 {
1503 return TRUE;
1504 }
1505 else
1506 {
1507 return uentryList_matchFields (c1->contents.su->fields,
1508 c2->contents.su->fields);
1509 }
885824d3 1510 }
1511 else
1512 {
28bf4b0b 1513 if (!cstring_isEmpty (c1->contents.su->name))
885824d3 1514 {
28bf4b0b 1515 return (cstring_equal (c1->contents.su->name, c2->contents.su->name));
1516 }
1517 else
1518 {
1519 if (!cstring_isEmpty (c2->contents.su->name))
1520 {
1521 return FALSE;
1522 }
1523
1524 llcontbuglit ("ctbase_genMatch: match fields");
1525 return (FALSE);
885824d3 1526 }
885824d3 1527 }
1528 default:
1529 llcontbug (message ("ctbase_genMatch: unknown type: %d\n", (int)c1tid));
1530 return (FALSE);
1531 }
1532}
1533
1534/*
1535** like ctbase_match, except for conjuncts:
1536** modifies conjuncts to match only
1537*/
1538
1539static bool
a0a162cd 1540ctbase_forceMatch (ctbase c1, ctbase c2) /*@modifies c1, c2@*/
885824d3 1541{
a0a162cd 1542 return (ctbase_genMatch (c1, c2, TRUE, FALSE, FALSE, FALSE));
885824d3 1543}
1544
1545static bool
1546ctbase_match (ctbase c1, ctbase c2) /*@modifies nothing@*/
1547{
a0a162cd 1548 return (ctbase_genMatch (c1, c2, FALSE, FALSE, FALSE, FALSE));
885824d3 1549}
1550
1551static bool
1552ctbase_matchDef (ctbase c1, ctbase c2) /*@modifies nothing@*/
1553{
a0a162cd 1554 return (ctbase_genMatch (c1, c2, FALSE, FALSE, TRUE, FALSE));
885824d3 1555}
1556
1557static bool
1558ctbase_matchArg (ctbase c1, ctbase c2)
1559{
a0a162cd 1560 return (ctbase_genMatch (c1, c2, FALSE, TRUE, FALSE, FALSE));
885824d3 1561}
1562
1563static /*@out@*/ /*@only@*/ /*@notnull@*/ ctbase
1564ctbase_new ()
1565{
1566 ctbase c = (ctbase) dmalloc (sizeof (*c));
1567
1568 nctbases++;
1569 /*
1570 if (nctbases % 100 == 0 && nctbases > lastnc)
1571 {
1572 llmsg (message ("ctbases: %d", nctbases));
1573 lastnc = nctbases;
1574 }
1575 */
1576 return (c);
1577}
1578
1579static /*@only@*/ ctbase
1580ctbase_createPrim (cprim p)
1581{
1582 ctbase c = ctbase_new ();
1583
1584 c->type = CT_PRIM;
1585 c->contents.prim = p;
1586
1587 return (c);
1588}
1589
1590static /*@observer@*/ ctbase
1591ctbase_getBool (void)
1592{
1593 /*@i@*/ return ctbase_createBool ();
1594}
1595
1596static ctbase
1597ctbase_createBool ()
1598{
1599 if (!ctbase_isDefined (ctbase_bool))
1600 {
1601 ctbase_bool = ctbase_new ();
1602 ctbase_bool->type = CT_BOOL;
1603 ctbase_bool->contents.prim = CTX_BOOL;
1604 }
1605
1606 /*@-retalias@*/ /*@-globstate@*/
1607 return ctbase_bool;
1608 /*@=retalias@*/ /*@=globstate@*/
1609}
1610
1611static /*@only@*/ ctbase
1612ctbase_createUser (typeId u)
1613{
1614 ctbase c = ctbase_new ();
1615
1616 c->type = CT_USER;
1617 c->contents.tid = u;
1618
1619 llassert (typeId_isValid (u));
1620
1621 return (c);
1622}
1623
1624static /*@only@*/ ctbase
1625ctbase_createEnum (/*@keep@*/ cstring etag, /*@keep@*/ enumNameList emembers)
1626{
1627 ctbase c = ctbase_new ();
1628
1629 c->type = CT_ENUM;
1630
1631 if (cstring_isUndefined (etag))
1632 {
1633 llcontbuglit ("Undefined enum tag!");
1634 etag = fakeTag ();
1635 }
1636
1637 c->contents.cenum = (tenum) dmalloc (sizeof (*c->contents.cenum));
1638 c->contents.cenum->tag = etag;
1639 c->contents.cenum->members = emembers;
1640
1641 return (c);
1642}
1643
1644static /*@observer@*/ cstring
1645ctbase_enumTag (/*@notnull@*/ ctbase ct)
1646{
1647 return (ct->contents.cenum->tag);
1648}
1649
1650static /*@only@*/ ctbase
1651ctbase_createAbstract (typeId u)
1652{
1653 ctbase c = ctbase_new ();
1654
1655 c->type = CT_ABST;
1656 c->contents.tid = u;
1657
1658 /* also check its abstract? */
1659
1660 llassert (typeId_isValid (c->contents.tid));
1661
1662 return (c);
1663}
1664
e5081f8c 1665static /*@only@*/ ctbase
1666ctbase_createNumAbstract (typeId u)
1667{
1668 ctbase c = ctbase_new ();
1669
1670 c->type = CT_NUMABST;
1671 c->contents.tid = u;
1672
1673 /* also check its abstract? */
1674
1675 llassert (typeId_isValid (c->contents.tid));
1676 return (c);
1677}
1678
885824d3 1679static /*@only@*/ ctbase
1680ctbase_createUnknown (void)
1681{
1682 if (!ctbase_isDefined (ctbase_unknown))
1683 {
1684 ctbase_unknown = ctbase_new ();
1685 ctbase_unknown->type = CT_UNKNOWN;
1686 ctbase_unknown->contents.prim = CTX_UNKNOWN;
1687 }
1688
1689 /*@-retalias@*/ /*@-globstate@*/
1690 return ctbase_unknown;
1691 /*@=retalias@*/ /*@=globstate@*/
1692}
1693
1694/*
1695** requires: result is not assigned to b
1696** (should copy, but no way to reclaim storage)
1697*/
1698
1699static /*@only@*/ ctbase
1700ctbase_makePointer (ctype b)
1701{
1702 ctbase c = ctbase_new ();
1703
1704 c->type = CT_PTR;
1705 c->contents.base = b;
1706
1707 return (c);
1708}
1709
1710static /*@only@*/ ctbase
1711ctbase_makeArray (ctype b)
1712{
1713 ctbase c = ctbase_new ();
1714
1715 c->type = CT_ARRAY;
1716 c->contents.base = b;
1717
1718 return (c);
1719}
1720
1721static /*@notnull@*/ /*@only@*/ ctbase
37ae0b5e 1722ctbase_makeFixedArray (ctype b, size_t size)
885824d3 1723{
1724 ctbase c = ctbase_new ();
1725
1726 c->type = CT_FIXEDARRAY;
1727
1728 c->contents.farray = (tfixed) dmalloc (sizeof (*c->contents.farray));
1729 c->contents.farray->base = b;
1730 c->contents.farray->size = size;
1731
1732 return (c);
1733}
1734
1735static ctype
1736ctbase_makeFunction (ctype b, /*@only@*/ uentryList p)
1737{
1738 ctbase c = ctbase_new ();
1739 ctype ct;
1740
1741 c->type = CT_FCN;
1742 c->contents.fcn = (cfcn) dmalloc (sizeof (*c->contents.fcn));
1743
1744 if (ctype_isFunction (b)) /* was: && ctype_isPointer (b)) */
1745 {
1746 ctbase ctb;
1747 ctype rval;
1748
1749 if (ctype_isPointer (b))
1750 {
1751 ctb = ctype_getCtbase (ctype_baseArrayPtr (b));
1752 }
1753 else
1754 {
1755 ctb = ctype_getCtbase (b);
1756 }
1757
1758 llassert (ctbase_isDefined (ctb));
1759 llassert (ctb->type == CT_FCN);
1760
1761 rval = ctype_makeFunction (ctb->contents.fcn->rval, p);
1762
1763 c->contents.fcn->rval = rval;
28bf4b0b 1764 c->contents.fcn->params = uentryList_copy (ctb->contents.fcn->params); /* no copy before */
885824d3 1765 }
1766 else
1767 {
1768 c->contents.fcn->rval = b;
28bf4b0b 1769 c->contents.fcn->params = uentryList_copy (p); /* no copy before */
885824d3 1770 /*@-branchstate@*/ /* p is really released on this branch */
1771 }
1772 /*@=branchstate@*/
1773
1774 ct = cttable_addComplex (c);
1775 return (ct); /* was: ctype_makePointer (ct)); */
1776}
1777
1778static ctype
1779ctbase_makeNFFunction (ctype b, /*@only@*/ uentryList p)
1780{
1781 ctbase c = ctbase_new ();
1782 ctype ct;
1783
1784 c->type = CT_FCN;
1785 c->contents.fcn = (cfcn) dmalloc (sizeof (*c->contents.fcn));
1786
1787 if (ctype_isFunction (b)) /* was && ctype_isPointer (b)) */
1788 {
1789 ctbase ctb;
1790 ctype rval;
1791
1792 if (ctype_isPointer (b))
1793 {
1794 ctb = ctype_getCtbase (ctype_baseArrayPtr (b));
1795 }
1796 else
1797 {
1798 ctb = ctype_getCtbase (b);
1799 }
1800
1801 llassert (ctbase_isDefined (ctb));
1802 llassert (ctb->type == CT_FCN);
1803
1804 rval = ctype_makeNFParamsFunction (ctb->contents.fcn->rval, p);
1805
1806 c->contents.fcn->rval = rval;
28bf4b0b 1807 c->contents.fcn->params = uentryList_copy (ctb->contents.fcn->params);
885824d3 1808 }
1809 else
1810 {
1811 c->contents.fcn->rval = b;
28bf4b0b 1812 c->contents.fcn->params = uentryList_copy (p);
885824d3 1813 /*@-branchstate@*/
1814 }
1815 /*@=branchstate@*/
1816
1817 ct = cttable_addComplex (c);
1818 return (ct); /* was: ctype_makePointer (ct)); */
1819}
1820
1821static /*@only@*/ ctbase
28bf4b0b 1822 ctbase_makeLiveFunction (ctype b, /*@only@*/ uentryList p)
885824d3 1823{
1824 ctbase c = ctbase_new ();
1825
1826 c->type = CT_FCN;
1827
1828 c->contents.fcn = (cfcn) dmalloc (sizeof (*c->contents.fcn));
1829 c->contents.fcn->rval = b;
1830 c->contents.fcn->params = p;
885824d3 1831
1832 /*@-mustfree@*/ return (c); /*@=mustfree@*/
1833}
1834
885824d3 1835static /*@observer@*/ /*@notnull@*/ ctbase
1836ctbase_realFunction (/*@dependent@*/ /*@notnull@*/ ctbase c)
1837{
1838 ctbase res;
1839
1840 if (c->type == CT_FCN)
1841 {
1842 return c;
1843 }
1844
1845 llassert (ctbase_isFunction (c));
1846
1847 res = ctype_getCtbase (c->contents.base);
1848
1849 llassert (ctbase_isDefined (res));
1850
1851 return (res);
1852}
1853
1854static bool
1855ctbase_isFunction (ctbase c)
1856{
1857 llassert (c != ctbase_undefined);
1858
1859 if (c->type == CT_FCN)
1860 {
1861 return TRUE;
1862 }
1863 else
1864 {
1865 if (c->type == CT_PTR)
1866 {
1867 ctbase fcn = ctype_getCtbase (ctbase_baseArrayPtr (c));
1868
1869 return (ctbase_isDefined (fcn) && fcn->type == CT_FCN);
1870 }
1871
1872 return FALSE;
1873 }
1874}
1875
1876/* doesn't copy c1 and c2 */
1877
1878static /*@only@*/ ctbase
1879 ctbase_makeConj (ctype c1, ctype c2, bool isExplicit)
1880{
1881 ctbase c = ctbase_new ();
1882
1883 c->type = CT_CONJ;
1884
1885 c->contents.conj = (tconj) dmalloc (sizeof (*c->contents.conj));
1886 c->contents.conj->a = c1;
1887 c->contents.conj->b = c2;
1888 c->contents.conj->isExplicit = isExplicit;
1889
1890 return (c);
1891}
1892
d5047b91 1893static bool ctbase_isAnytype (/*@notnull@*/ ctbase b)
1894{
1895 /*
1896 ** A unknown|dne conj is a special representation for an anytype.
1897 */
1898
1899 if (b->type == CT_CONJ)
1900 {
1901 /*@access ctype@*/
1902 return (b->contents.conj->a == ctype_unknown
1903 && b->contents.conj->b == ctype_dne);
1904 /*@noaccess ctype@*/
1905 }
1906
1907 return FALSE;
1908}
1909
885824d3 1910static ctype
1911ctbase_getConjA (/*@notnull@*/ ctbase c)
1912{
1913 llassert (c->type == CT_CONJ);
1914 return (c->contents.conj->a);
1915}
1916
1917static ctype
1918ctbase_getConjB (/*@notnull@*/ ctbase c)
1919{
1920 llassert (c->type == CT_CONJ);
1921 return (c->contents.conj->b);
1922}
1923
1924static bool
1925ctbase_isExplicitConj (/*@notnull@*/ ctbase c)
1926{
1927 llassert (c->type == CT_CONJ);
1928 return (c->contents.conj->isExplicit);
1929}
1930
1931static /*@only@*/ ctbase
1932ctbase_createStruct (/*@only@*/ cstring n, /*@only@*/ uentryList f)
1933{
1934 ctbase c = ctbase_new ();
1935
1936 c->type = CT_STRUCT;
1937
1938 c->contents.su = (tsu) dmalloc (sizeof (*c->contents.su));
1939 c->contents.su->name = n;
1940 c->contents.su->fields = f;
1941
1942 return (c);
1943}
1944
1945static /*@observer@*/ uentryList
1946ctbase_getuentryList (/*@notnull@*/ ctbase c)
1947{
1948 c = ctbase_realType (c);
1949
1950 if (!(c->type == CT_STRUCT || c->type == CT_UNION))
1951 llfatalbug (message ("ctbase_getuentryList: bad invocation: %q", ctbase_unparse (c)));
1952
1953 return (c->contents.su->fields);
1954}
1955
1956static ctbase
1957ctbase_createUnion (/*@keep@*/ cstring n, /*@only@*/ uentryList f)
1958{
1959 ctbase c = ctbase_new ();
1960
1961 c->type = CT_UNION;
1962
1963 c->contents.su = (tsu) dmalloc (sizeof (*c->contents.su));
1964 c->contents.su->name = n;
1965 c->contents.su->fields = f;
1966
1967 return (c);
1968}
1969
1970static ctype
1971ctbase_baseArrayPtr (/*@notnull@*/ ctbase c)
1972{
1973 ctuid ct;
1974 c = ctbase_realType (c);
1975 ct = c->type;
1976
1977 if (ct == CT_FIXEDARRAY)
1978 {
1979 return c->contents.farray->base;
1980 }
1981 else
1982 {
1983 llassert (ctuid_isAP (ct));
1984
1985 return c->contents.base;
1986 }
1987}
1988
1989static ctype
1990ctbase_baseFunction (/*@notnull@*/ ctbase c)
1991{
1992 ctbase_fixUser (c);
1993 c = ctbase_realFunction (c);
1994
1995 if (c->type != CT_FCN)
1996 {
1997 llfatalbug (message ("ctbase_baseFunction: bad call: %q", ctbase_unparse (c)));
1998 }
1999
2000 return (c->contents.fcn->rval);
2001}
2002
2003static uentryList
2004ctbase_argsFunction (/*@notnull@*/ ctbase c)
2005{
2006 ctbase_fixUser (c);
2007 c = ctbase_realFunction (c);
2008
2009 if (c->type != CT_FCN)
2010 {
2011 llfatalbug (message ("ctbase_argsFunction: bad call: %q",
2012 ctbase_unparse (c)));
2013 }
2014 return (c->contents.fcn->params);
2015}
2016
2017static bool
2018ctbase_baseisExpFcn (ctype c)
2019{
2020 ctbase cb;
2021 c = ctype_removePointers (c);
2022
2023 cb = ctype_getCtbase (c);
2024 llassert (ctbase_isDefined (cb));
2025
2026 if (cb->type == CT_FCN)
2027 {
28bf4b0b 2028 c = ctype_removePointers (ctype_getReturnType (c));
885824d3 2029
2030 cb = ctype_getCtbase (c);
2031 llassert (ctbase_isDefined (cb));
2032
2033 return (cb->type == CT_EXPFCN);
2034 }
2035 return FALSE;
2036}
2037
2038/*
2039** ctbase_newBase behaves specially when p is a CONJ:
2040**
2041** c -> conj (newBase (c, p.a), p.b)
2042*/
2043
2044static ctype
2045ctbase_newBase (ctype c, ctype p)
2046{
2047 ctbase cb;
2048
2049 DPRINTF (("New base: %s / %s", ctype_unparse (c), ctype_unparse (p)));
2050
28bf4b0b 2051 if (ctype_isUndefined (c) || ctype_isUnknown (c))
885824d3 2052 {
2053 return p;
2054 }
2055
28bf4b0b 2056 cb = ctype_getCtbase (c);
2057
885824d3 2058 if (ctype_isConj (p))
2059 {
2060 ctbase pb = ctype_getCtbase (p);
2061
2062 llassert (ctbase_isDefined (pb));
2063
2064 if (pb->contents.conj->isExplicit)
2065 {
2066 return (ctype_makeExplicitConj (ctype_newBase (c, pb->contents.conj->a),
2067 pb->contents.conj->b));
2068
2069 }
2070 else
2071 {
2072 return (ctype_makeConj (ctype_newBase (c, pb->contents.conj->a),
2073 pb->contents.conj->b));
2074
2075 }
2076 }
2077
2078 if (ctbase_baseisExpFcn (c))
2079 {
2080 return (ctbase_newBaseExpFcn (c, p));
2081 }
2082
2083 llassert (ctbase_isDefined (cb));
2084
2085 switch (cb->type)
2086 {
2087 case CT_UNKNOWN:
2088 case CT_PRIM:
2089 case CT_USER:
2090 case CT_ENUM:
2091 case CT_ABST:
e5081f8c 2092 case CT_NUMABST:
885824d3 2093 case CT_STRUCT:
2094 case CT_UNION:
2095 case CT_EXPFCN:
2096 return (p);
2097
2098 case CT_PTR:
2099 {
2100 ctype ret;
2101 ctype cbn;
2102
2103 cbn = ctbase_newBase (cb->contents.base, p);
2104 ret = ctype_makePointer (cbn);
2105
2106 return ret;
2107 }
2108 case CT_FIXEDARRAY:
2109 return (ctype_makeFixedArray (ctbase_newBase (cb->contents.farray->base, p),
2110 cb->contents.farray->size));
2111 case CT_ARRAY:
2112 return (ctype_makeArray (ctbase_newBase (cb->contents.base, p)));
2113 case CT_FCN:
28bf4b0b 2114 return (ctype_makeRawFunction (ctbase_newBase (cb->contents.fcn->rval, p),
885824d3 2115 cb->contents.fcn->params));
2116 case CT_CONJ:
2117 return (ctype_makeConjAux (ctbase_newBase (cb->contents.conj->a, p),
2118 ctbase_newBase (cb->contents.conj->b, p),
2119 cb->contents.conj->isExplicit));
2120 default:
2121 llcontbug (message ("ctbase_newBase: bad ctbase: %q", ctbase_unparse (cb)));
2122 return (p);
2123 }
2124 BADEXIT;
2125}
2126
2127static ctype
2128ctbase_newBaseExpFcn (ctype c, ctype p)
2129{
2130 ctbase cb = ctype_getCtbase (c);
2131 ctbase tcb;
2132 ctype ret, tmpct;
2133 ctype fp = ctype_unknown;
2134 uentryList ctargs = ctype_argsFunction (c);
2135
2136 /*
2137 ** okay, this is really ugly...
2138 **
2139 ** pointers inside <expf> mean pointers to the function;
2140 ** pointers outside <expf> are pointers to the return value;
2141 ** because its a function there is one superfluous pointer.
2142 */
2143
2144 /*
2145 ** bf is a ctype, used to derived structure of cb
2146 */
2147
2148 if (!ctbase_isFunction (cb))
2149 llbuglit ("ctbase_newBaseExpFcn: expFcn -> not a function");
2150
28bf4b0b 2151 tmpct = ctype_getBaseType (ctype_getReturnType (c));
885824d3 2152
2153 /*
2154 ** pointers before expfcn -> p are pointers to function, not result
2155 **
2156 */
2157
2158 tcb = ctype_getCtbase (tmpct);
2159
2160 llassert (ctbase_isDefined (tcb));
2161 tmpct = tcb->contents.base;
2162
2163 /*
2164 ** record pointers to base in fp
2165 */
2166
2167 while (!ctype_isUnknown (tmpct))
2168 {
2169 if (ctype_isExpFcn (tmpct)) {
2170 ctbase ttcb = ctype_getCtbase (tmpct);
2171
2172 /*
2173 ** evs 2000-05-16: This is necessary to deal with function pointers in parens.
2174 ** The whole function pointer parsing is a major kludge, but it seems to work,
2175 ** and I'm only embarrassed by it when I haven't look at the C spec recently...
2176 */
2177
2178 llassert (ctbase_isDefined (ttcb));
2179 tmpct = ttcb->contents.base;
2180 llassert (!ctype_isUnknown (tmpct));
2181 }
2182
2183 switch (ctype_getCtKind (tmpct))
2184 {
2185 case CTK_PTR:
2186 fp = ctype_makePointer (fp);
2187 /*@switchbreak@*/ break;
2188 case CTK_ARRAY:
2189 fp = ctype_makeArray (fp);
2190 /*@switchbreak@*/ break;
2191 case CTK_COMPLEX:
2192 {
2193 ctbase fbase = ctype_getCtbase (tmpct);
2194
2195 if (ctbase_isFunction (fbase))
2196 {
2197 fp = ctype_makeFunction (fp, uentryList_copy (ctargs));
2198 ctargs = ctbase_argsFunction (fbase);
2199 }
2200 else
2201 {
2202 llbug
2203 (message
2204 ("ctbase_newBaseExpFcn: fixing expfunction: bad complex type: %s [base: %q]",
2205 ctype_unparse (tmpct), ctbase_unparse (fbase)));
2206 }
2207 goto exitLoop;
2208 }
2209 default:
2210 {
2211 llcontbug
2212 (message ("ctbase_newBaseExpFcn: fixing expfunction: bad type: %s",
2213 ctype_unparse (tmpct)));
2214 goto exitLoop;
2215 }
2216 }
2217 tmpct = ctype_baseArrayPtr (tmpct);
2218 }
2219
2220 exitLoop:
28bf4b0b 2221 tmpct = ctype_getReturnType (c);
885824d3 2222
2223 /*
2224 ** pointers to expf are pointers to return value
2225 */
2226
2227 while (!ctype_isExpFcn (tmpct))
2228 {
2229 switch (ctype_getCtKind (tmpct))
2230 {
2231 case CTK_PTR:
2232 p = ctype_makePointer (p);
2233 /*@switchbreak@*/ break;
2234 case CTK_ARRAY:
2235 p = ctype_makeArray (p);
2236 /*@switchbreak@*/ break;
2237 case CTK_COMPLEX:
2238 {
2239 ctbase fbase = ctype_getCtbase (tmpct);
2240
2241 if (ctbase_isFunction (fbase))
2242 {
2243 p = ctype_makeFunction (p, uentryList_copy (ctbase_argsFunction (fbase)));
2244 }
2245 else
2246 {
2247 llbug
2248 (message
2249 ("ctbase_newBaseExpFcn: fixing expfunction: bad complex type: %s",
2250 ctype_unparse (tmpct)));
2251 }
2252 goto exitLoop2;
2253 }
2254
2255 default:
2256 {
2257 llcontbug
2258 (message ("ctbase_newBaseExpFcn: fixing expfunction2: bad type: %t",
2259 tmpct));
2260 goto exitLoop2;
2261 }
2262 }
2263 tmpct = ctype_baseArrayPtr (tmpct);
2264 }
2265
2266 exitLoop2:
2267
2268 /*
2269 ** pointers to fp are pointers to function type
2270 */
2271
28bf4b0b 2272 ret = ctype_makeRawFunction (p, uentryList_copy (ctargs));
885824d3 2273
2274 while (ctype_getCtKind (fp) > CTK_PLAIN)
2275 {
2276 switch (ctype_getCtKind (fp))
2277 {
2278 case CTK_PTR:
2279 ret = ctype_makePointer (ret);
2280 /*@switchbreak@*/ break;
2281 case CTK_ARRAY:
2282 ret = ctype_makeArray (ret);
2283 /*@switchbreak@*/ break;
2284 case CTK_COMPLEX:
2285 {
2286 ctbase fbase = ctype_getCtbase (fp);
2287
2288 if (ctbase_isFunction (fbase))
2289 {
2290 ret =
2291 ctype_makeFunction (ret,
2292 uentryList_copy (ctbase_argsFunction (fbase)));
2293 }
2294 else
2295 {
2296 BADBRANCH;
2297 }
2298 goto exitLoop3;
2299 }
2300
2301 default:
2302 {
2303 llcontbug (message ("post-fixing expfunction: bad type: %t", fp));
2304 goto exitLoop3;
2305 }
2306 }
2307 fp = ctype_baseArrayPtr (fp);
2308 }
2309
2310 exitLoop3:
2311 return (ret);
2312}
2313
2314/*
2315** returns lowest level base of c: plain type
2316*/
2317
2318static /*@notnull@*/ /*@only@*/ ctbase
2319ctbase_getBaseType (/*@notnull@*/ ctbase c)
2320{
2321 switch (c->type)
2322 {
2323 case CT_UNKNOWN:
2324 case CT_PRIM:
2325 case CT_USER:
2326 case CT_ENUM:
2327 case CT_ENUMLIST:
2328 case CT_BOOL:
2329 case CT_ABST:
e5081f8c 2330 case CT_NUMABST:
885824d3 2331 case CT_FCN:
2332 case CT_STRUCT:
2333 case CT_UNION:
2334 return (ctbase_copy (c));
2335
2336 case CT_PTR:
2337 case CT_ARRAY:
2338 return (ctbase_getBaseType (ctype_getCtbaseSafe (c->contents.base)));
2339
2340 case CT_FIXEDARRAY:
2341 return (ctbase_getBaseType (ctype_getCtbaseSafe (c->contents.farray->base)));
2342 case CT_CONJ: /* base type of A conj branch? */
2343 return (ctbase_getBaseType (ctype_getCtbaseSafe (c->contents.conj->a)));
2344 case CT_EXPFCN:
2345 return (ctbase_copy (c));
2346
2347 default:
2348 llfatalbug (message ("ctbase_getBaseType: bad ctbase: %q", ctbase_unparse (c)));
2349 }
2350
2351 BADEXIT;
2352}
2353
2354static int
2355ctbase_compare (ctbase c1, ctbase c2, bool strict)
2356{
2357 ctuid c1tid, c2tid;
2358
2359 if (ctbase_isUndefined (c1) || ctbase_isUndefined (c2))
2360 {
2361 llcontbuglit ("ctbase_compare: undefined ctbase");
2362 return -1;
2363 }
2364
2365 c1tid = c1->type;
2366 c2tid = c2->type;
2367
2368 if (c1tid < c2tid)
2369 return -1;
2370 if (c1tid > c2tid)
2371 return 1;
2372
2373 switch (c1tid)
2374 {
2375 case CT_UNKNOWN:
2376 return 0;
2377 case CT_PRIM:
2378 return (int_compare (c1->contents.prim, c2->contents.prim));
2379 case CT_BOOL:
2380 return 0;
2381 case CT_USER:
2382 return (int_compare (c1->contents.tid, c2->contents.tid));
2383 case CT_ENUMLIST:
2384 return 1;
2385 case CT_ENUM: /* for now, keep like abstract */
2386 case CT_ABST:
e5081f8c 2387 case CT_NUMABST:
885824d3 2388 return (int_compare (c1->contents.tid, c2->contents.tid));
2389 case CT_PTR:
2390 return (ctype_compare (c1->contents.base, c2->contents.base));
2391 case CT_FIXEDARRAY:
2392 INTCOMPARERETURN (c1->contents.farray->size, c2->contents.farray->size);
2393
2394 return (ctype_compare (c1->contents.farray->base,
2395 c2->contents.farray->base));
2396 case CT_ARRAY:
2397 return (ctype_compare (c1->contents.base, c2->contents.base));
2398 case CT_FCN:
2399 {
2400 COMPARERETURN (ctype_compare (c1->contents.fcn->rval, c2->contents.fcn->rval));
2401
2402 if (strict)
2403 {
2404 return (uentryList_compareStrict (c1->contents.fcn->params,
2405 c2->contents.fcn->params));
2406 }
2407 else
2408 {
2409 return (uentryList_compareParams (c1->contents.fcn->params,
2410 c2->contents.fcn->params));
2411 }
2412 }
2413 case CT_EXPFCN:
2414 return (ctype_compare (c1->contents.base, c2->contents.base));
2415 case CT_STRUCT:
2416 case CT_UNION:
a0a162cd 2417 /* evs 2000-07-28: this block was missing! */
2418 if (strict) {
2419 int ncmp = cstring_compare (c1->contents.su->name,
2420 c2->contents.su->name);
2421
2422 if (ncmp != 0) {
2423 if (isFakeTag (c1->contents.su->name)
2424 && isFakeTag (c2->contents.su->name)) {
2425 ; /* If they are both fake struct tags, don't require match. */
2426 } else {
2427 return ncmp;
2428 }
2429 }
2430 }
2431
28bf4b0b 2432 DPRINTF (("Comparing fields: %s / %s",
2433 ctbase_unparse (c1),
2434 ctbase_unparse (c2)));
2435
885824d3 2436 return (uentryList_compareFields (c1->contents.su->fields,
2437 c2->contents.su->fields));
2438 case CT_CONJ:
2439 {
2440 COMPARERETURN (ctype_compare (c1->contents.conj->a,
2441 c2->contents.conj->a));
2442 COMPARERETURN (ctype_compare (c1->contents.conj->b,
2443 c2->contents.conj->b));
2444 return (bool_compare (c1->contents.conj->isExplicit,
2445 c2->contents.conj->isExplicit));
2446 }
2447 }
2448 BADEXIT;
2449}
2450
2451static int
2452ctbase_compareStrict (/*@notnull@*/ ctbase c1, /*@notnull@*/ ctbase c2)
2453{
2454 return (ctbase_compare (c1, c2, TRUE));
2455}
2456
2457static bool ctbase_equivStrict (/*@notnull@*/ ctbase c1, /*@notnull@*/ ctbase c2)
2458{
2459 return (ctbase_compareStrict (c1,c2) == 0);
2460}
2461
2462static bool ctbase_equiv (/*@notnull@*/ ctbase c1, /*@notnull@*/ ctbase c2)
2463{
2464 return (ctbase_compare (c1, c2, FALSE) == 0);
2465}
2466
2467static bool
2468ctbase_isKind (/*@notnull@*/ ctbase c, ctuid kind)
2469{
2470 ctuid ck = c->type;
2471
2472 if (ck == kind)
2473 return TRUE;
2474
2475 if (ck == CT_CONJ)
2476 return (ctbase_isKind (ctype_getCtbaseSafe (c->contents.conj->a), kind) ||
2477 ctbase_isKind (ctype_getCtbaseSafe (c->contents.conj->b), kind));
2478
2479 return FALSE;
2480}
2481
2482static bool
2483ctbase_isKind2 (/*@notnull@*/ ctbase c, ctuid kind1, ctuid kind2)
2484{
2485 ctuid ck = c->type;
2486
2487 if (ck == kind1 || ck == kind2)
2488 return TRUE;
2489
2490 if (ck == CT_CONJ)
2491 return (ctbase_isKind2 (ctype_getCtbaseSafe (c->contents.conj->a), kind1, kind2) ||
2492 ctbase_isKind2 (ctype_getCtbaseSafe (c->contents.conj->b), kind1, kind2));
2493
2494 return FALSE;
2495}
2496
2497static bool
2498ctbase_isAbstract (/*@notnull@*/ ctbase c)
2499{
e5081f8c 2500 return (c->type == CT_ABST || c->type == CT_NUMABST);
2501}
2502
2503static bool
2504ctbase_isNumAbstract (/*@notnull@*/ ctbase c)
2505{
2506 return (c->type == CT_NUMABST);
885824d3 2507}
2508
2509static bool ctbase_isUA (ctbase c)
2510{
e5081f8c 2511 return (ctbase_isDefined (c) && (ctuid_isAnyUserType (c->type)));
885824d3 2512}
2513
2514static bool
2515ctbase_almostEqual (ctbase c1, ctbase c2)
2516{
2517 ctuid c1tid, c2tid;
2518
2519 /* undefined types never match */
2520
2521 if (ctbase_isUndefined (c1) || ctbase_isUndefined (c2))
2522 return FALSE;
2523
2524 c1tid = c1->type;
2525 c2tid = c2->type;
2526
2527 if (c1tid == CT_FIXEDARRAY && c2tid == CT_ARRAY)
2528 {
2529 return (ctbase_almostEqual (ctype_getCtbase (c1->contents.farray->base),
2530 ctype_getCtbase (c2->contents.base)));
2531 }
2532
2533 if (c2tid == CT_FIXEDARRAY && c1tid == CT_ARRAY)
2534 {
2535 return (ctbase_almostEqual (ctype_getCtbase (c1->contents.base),
2536 ctype_getCtbase (c2->contents.farray->base)));
2537 }
2538
2539 if (c1tid != c2tid)
2540 return FALSE;
2541
2542 switch (c1tid)
2543 {
2544 case CT_UNKNOWN:
2545 return TRUE;
2546 case CT_PRIM:
2547 return (cprim_equal (c1->contents.prim, c2->contents.prim));
2548 case CT_BOOL:
2549 return TRUE;
2550 case CT_ABST:
e5081f8c 2551 case CT_NUMABST:
885824d3 2552 case CT_USER:
2553 return (typeId_equal (c1->contents.tid, c2->contents.tid));
2554 case CT_ENUM:
2555 return (cstring_equal (c1->contents.cenum->tag, c2->contents.cenum->tag));
2556 case CT_PTR:
2557 return (ctype_almostEqual (c1->contents.base, c2->contents.base));
2558 case CT_FIXEDARRAY:
2559 return (ctype_almostEqual (c1->contents.farray->base,
2560 c2->contents.farray->base));
2561 case CT_ARRAY:
2562 return (ctype_almostEqual (c1->contents.base, c2->contents.base));
2563 case CT_FCN:
2564 return (ctype_almostEqual (c1->contents.fcn->rval, c2->contents.fcn->rval)
2565 && uentryList_matchParams (c1->contents.fcn->params,
2566 c2->contents.fcn->params, FALSE, TRUE));
2567 case CT_STRUCT:
2568 case CT_UNION:
2569 if (!cstring_isEmpty (c1->contents.su->name))
2570 {
2571 return (cstring_equal (c1->contents.su->name, c2->contents.su->name));
2572 }
2573 else
2574 {
2575 if (!cstring_isEmpty (c2->contents.su->name))
2576 {
2577 return FALSE;
2578 }
2579
2580 llcontbuglit ("ctbase_almostEqual: match fields");
2581 return (FALSE);
2582 }
2583 default:
2584 llcontbug (message ("ctbase_almostEqual: unknown type: %d\n", (int)c1tid));
2585 return (FALSE);
2586 }
2587}
28bf4b0b 2588
2589/*drl added July 02, 001
2590 called by ctype_getArraySize
2591*/
2592
37ae0b5e 2593size_t ctbase_getArraySize (ctbase ctb)
28bf4b0b 2594{
37ae0b5e 2595 /*drl 1/25/2002 fixed discovered by Jim Francis */
0e5499ac 2596 ctbase r;
28bf4b0b 2597
0e5499ac 2598 llassert (ctbase_isDefined (ctb) );
2599 r = ctbase_realType (ctb);
2600 llassert (ctbase_isFixedArray(r) );
2601
0e5499ac 2602 return (r->contents.farray->size);
28bf4b0b 2603}
e5081f8c 2604
2605bool ctbase_isBigger (ctbase ct1, ctbase ct2)
2606{
2607 if (ct1 != NULL && ct2 != NULL
2608 && (ct1->type == CT_PRIM && ct2->type == CT_PRIM))
2609 {
2610 /* Only compare sizes for primitives */
2611 cprim cp1 = ct1->contents.prim;
2612 cprim cp2 = ct2->contents.prim;
2613 int nbits1 = cprim_getExpectedBits (cp1);
2614 int nbits2 = cprim_getExpectedBits (cp2);
2615
2616 if (nbits1 > nbits2) {
2617 return TRUE;
2618 } else {
2619 return FALSE;
2620 }
2621 }
2622 else
2623 {
2624 return FALSE;
2625 }
2626}
This page took 0.529311 seconds and 5 git commands to generate.