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