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