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