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