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