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