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