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