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