2 ** Splint
- annotation-assisted static program checker
3 ** Copyright
(C
) 1994-2003 University of Virginia
,
4 ** Massachusetts Institute of Technology
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.
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.
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.
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
27 ** NOTE
: This is not a stand-alone source file
, but is included in ctype.c.
28 ** (This is necessary because there is no other way in C to have a
29 ** hidden scope
, besides at the file level.
)
34 abst_typedef
/*@null@
*/ struct s_ctbase
*ctbase
;
36 /*@function static bool ctuid_isAnyUserType
(sef ctuid p_cid
) @
*/
38 /*@
-macrofcndecl@
*/ /*@
-macroparams@
*/
39 # define ctuid_isAnyUserType
(cid
) \
40 ((cid
) == CT_ABST ||
(cid
) == CT_USER ||
(cid
) == CT_NUMABST
)
41 /*@
=macrofcndecl@
*/ /*@
=macroparams@
*/
43 /*:private
:*/ typedef struct
{
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
*/
52 typedef
/*@only@
*/ ctentry o_ctentry
;
57 /*@relnull@
*/ /*@only@
*/ o_ctentry
*entries
;
58 /* memoize matches...maybe in context?
*/
61 extern bool ctentry_isBogus
(/*@sef@
*/ ctentry p_c
) /*@
*/;
62 # define ctentry_isBogus
(c
) \
63 ((c
)->kind
== CTK_INVALID ||
(c
)->kind
== CTK_DNE
)
65 static cttable cttab
= { 0, 0, NULL };
67 static
/*@notnull@
*/ /*@only@
*/ ctbase ctbase_createAbstract
(typeId p_u
);
68 static
/*@notnull@
*/ /*@only@
*/ ctbase ctbase_createNumAbstract
(typeId p_u
);
69 static
/*@observer@
*/ cstring ctentry_doUnparse
(ctentry p_c
) /*@modifies p_c@
*/;
70 static
/*@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
);
73 static
/*@only@
*/ ctentry ctentry_makeNew
(ctkind p_ctk
, /*@only@
*/ ctbase p_c
);
74 static
/*@only@
*/ cstring ctentry_unparse
(ctentry p_c
) /*@
*/ ;
76 static void cttable_grow
(void
);
77 static ctype cttable_addDerived
(ctkind p_ctk
, /*@keep@
*/ ctbase p_cnew
, ctype p_base
);
78 static ctype cttable_addFull
(/*@keep@
*/ ctentry p_cnew
);
79 static bool ctentry_isInteresting
(ctentry p_c
) /*@
*/;
80 static
/*@notnull@
*/ /*@only@
*/ ctbase ctbase_makeFixedArray
(ctype p_b
, size_t p_size
) /*@
*/ ;
81 static bool ctbase_isAnytype
(/*@notnull@
*/ ctbase p_b
) /*@
*/ ;
84 ** These are file-static macros
(used in ctype.c
). No way to
85 ** declare them as static in C.
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
))
100 # define ctbase_fixUser
(c
) (c
= ctbase_realType
(c
))
101 /*@
=allmacros@
*/ /*@
=macrospec@
*/ /*@
=namechecks@
*/
103 static ctype cttable_addComplex
(/*@notnull@
*/ /*@only@
*/ ctbase p_cnew
);
104 static
/*@observer@
*/ ctbase ctype_getCtbase
(ctype p_c
) /*@
*/ ;
105 static ctype ctype_makeConjAux
(ctype p_c1
, ctype p_c2
, bool p_isExplicit
) /*@
*/ ;
106 static
/*@notnull@
*/ /*@observer@
*/ ctbase ctype_getCtbaseSafe
(ctype p_c
) /*@
*/ ;
107 static
/*@observer@
*/ ctentry ctype_getCtentry
(ctype p_c
) /*@
*/ ;
108 static
/*@observer@
*/ /*@notnull@
*/ ctbase
109 ctbase_realType
(/*@notnull@
*/ ctbase p_c
) /*@
*/ ;
110 static bool ctbase_isPointer
(/*@notnull@
*/ /*@dependent@
*/ ctbase p_c
) /*@
*/ ;
111 static bool ctbase_isEitherArray
(/*@notnull@
*/ /*@dependent@
*/ ctbase p_c
) /*@
*/ ;
112 static
/*@observer@
*/ enumNameList ctbase_elist
(ctbase p_c
) /*@
*/ ;
113 static
/*@only@
*/ cstring ctbase_unparse
(ctbase p_c
) /*@
*/ ;
114 static
/*@only@
*/ cstring ctbase_unparseDeep
(ctbase p_c
) /*@
*/ ;
115 static void ctbase_free
(/*@only@
*/ ctbase p_c
);
116 static
/*@notnull@
*/ /*@only@
*/ ctbase ctbase_createPrim
(cprim p_p
) /*@
*/ ;
117 static
/*@notnull@
*/ /*@only@
*/ ctbase ctbase_createBool
(void
) /*@
*/ ;
118 static
/*@notnull@
*/ /*@observer@
*/ ctbase ctbase_getBool
(void
) /*@
*/ ;
119 static
/*@notnull@
*/ /*@only@
*/ ctbase ctbase_createUser
(typeId p_u
) /*@
*/ ;
121 static
/*@notnull@
*/ /*@only@
*/ ctbase
122 ctbase_createStruct
(/*@only@
*/ cstring p_n
, /*@only@
*/ uentryList p_f
);
124 static
/*@notnull@
*/ /*@only@
*/ ctbase
125 ctbase_createUnion
(/*@keep@
*/ cstring p_n
, /*@only@
*/ uentryList p_f
);
126 static
/*@notnull@
*/ /*@only@
*/ ctbase ctbase_createEnum
(/*@keep@
*/ cstring p_etag
, /*@keep@
*/ enumNameList p_emembers
);
127 static
/*@notnull@
*/ /*@only@
*/ ctbase ctbase_createUnknown
(void
);
128 static bool ctbase_match
(ctbase p_c1
, ctbase p_c2
) /*@modifies nothing@
*/;
129 static bool ctbase_matchDef
(ctbase p_c1
, ctbase p_c2
) /*@modifies nothing@
*/;
130 static bool ctbase_genMatch
(ctbase p_c1
, ctbase p_c2
, bool p_force
, bool p_arg
, bool p_def
, bool p_deep
);
131 static bool ctbase_isAbstract
(/*@notnull@
*/ ctbase p_c
) /*@
*/ ;
132 static
/*@notnull@
*/ /*@only@
*/ ctbase ctbase_makePointer
(ctype p_b
) /*@
*/ ;
133 static
/*@notnull@
*/ /*@only@
*/ ctbase ctbase_makeArray
(ctype p_b
) /*@
*/ ;
134 static
/*@notnull@
*/ ctype
135 ctbase_makeFunction
(ctype p_b
, /*@only@
*/ uentryList p_p
) /*@
*/ ;
136 static
/*@notnull@
*/ /*@observer@
*/ ctbase
137 ctbase_realFunction
(/*@notnull@
*/ /*@dependent@
*/ ctbase p_c
) /*@
*/ ;
138 static ctype ctbase_baseArrayPtr
(/*@notnull@
*/ ctbase p_c
) /*@
*/ ;
139 static ctype ctbase_baseFunction
(/*@notnull@
*/ ctbase p_c
) /*@
*/ ;
140 static
/*@observer@
*/ uentryList ctbase_argsFunction
(/*@notnull@
*/ ctbase p_c
) /*@
*/ ;
141 static
/*@observer@
*/ uentryList ctbase_getuentryList
(/*@notnull@
*/ ctbase p_c
) /*@
*/ ;
142 static ctype ctbase_newBase
(ctype p_c
, ctype p_p
) /*@
*/ ;
143 static ctype ctbase_newBaseExpFcn
(ctype p_c
, ctype p_p
) /*@
*/ ;
144 static bool ctbase_isFixedArray
(/*@notnull@
*/ ctbase p_c
) /*@
*/ ;
147 extern int cttable_lastIndex
(void
);
148 # define cttable_lastIndex
() (cttab.size
- 1)
154 /*@only@
*/ uentryList params
;
173 enumNameList members
;
184 cprim prim
; /* primitive
*/
185 typeId tid
; /* abstract
, user
*/
186 ctype base
; /* ptr
, array
*/
187 cfcn fcn
; /* function
*/
188 tsu su
; /* struct union
*/
189 tenum cenum
; /* enum
*/
190 tconj conj
; /* conj
*/
191 tfixed farray
; /* fixed array
*/
200 static
/*@falsenull@
*/ bool ctbase_isUA
(ctbase p_c
) /*@
*/ ;
201 static bool ctbase_isKind
(/*@notnull@
*/ ctbase p_c
, ctuid p_kind
) /*@
*/ ;
202 static
/*@falsenull@
*/ bool ctbase_isFunction
(ctbase p_c
) /*@
*/ ;
204 /*@constant null ctbase ctbase_undefined
; @
*/
205 # define ctbase_undefined
((ctbase
)0)
207 static
/*@owned@
*/ ctbase ctbase_bool
= ctbase_undefined
;
208 static
/*@owned@
*/ ctbase ctbase_unknown
= ctbase_undefined
;
210 static
/*@falsenull@
*/ bool ctbase_isDefined
(ctbase c
) /*@
*/
212 return
((c
) != ctbase_undefined
);
215 static
/*@truenull@
*/ bool ctbase_isUndefined
(ctbase c
)
217 return
((c
) == ctbase_undefined
);
220 static ctkind ctype_getCtKind
(ctype c
)
222 ctentry ce
= ctype_getCtentry
(c
);
224 return ctentry_getKind
(ce
);
227 static bool ctbase_isUser
(ctbase c
)
229 if
(ctbase_isDefined
(c
))
231 return
(ctbase_isKind
(c
, CT_USER
));
239 static bool ctbase_isEnum
(ctbase c
)
241 if
(ctbase_isDefined
(c
))
243 return
(ctbase_isKind
(c
, CT_ENUM
));
251 static bool ctbase_isExpFcn
(ctbase c
)
253 if
(ctbase_isDefined
(c
))
255 return
(c-
>type
== CT_EXPFCN
);
263 static
/*@falsenull@
*/ bool ctbase_isConj
(ctbase c
)
265 if
(ctbase_isDefined
(c
))
267 return
(c-
>type
== CT_CONJ
);
275 static bool ctuid_isAP
(ctuid c
) /*@
*/
277 return
(c
== CT_ARRAY || c
== CT_PTR
);
280 static typeId ctbase_typeId
(ctbase p_c
);
281 static
/*@only@
*/ cstring ctbase_dump
(ctbase p_c
);
282 static
/*@only@
*/ ctbase ctbase_undump
(char
**p_c
) /*@requires maxRead
(*p_c
) >= 2 @
*/;
283 static int ctbase_compare
(ctbase p_c1
, ctbase p_c2
, bool p_strict
);
284 static bool ctbase_matchArg
(ctbase p_c1
, ctbase p_c2
);
285 static
/*@notnull@
*/ /*@only@
*/ ctbase
286 ctbase_makeConj
(ctype p_c1
, ctype p_c2
, bool p_isExplicit
) /*@
*/ ;
287 static ctype ctbase_getConjA
(/*@notnull@
*/ ctbase p_c
) /*@
*/ ;
288 static ctype ctbase_getConjB
(/*@notnull@
*/ ctbase p_c
) /*@
*/ ;
289 static bool ctbase_isExplicitConj
(/*@notnull@
*/ ctbase p_c
) /*@
*/ ;
290 static bool ctbase_forceMatch
(ctbase p_c1
, ctbase p_c2
) /*@modifies p_c1
, p_c2@
*/ ;
291 static
/*@notnull@
*/ /*@only@
*/ ctbase ctbase_expectFunction
(ctype p_c
);
292 static bool ctbase_isVoidPointer
(/*@notnull@
*/ /*@dependent@
*/ ctbase p_c
) /*@
*/ ;
293 static bool ctbase_isUnion
(/*@notnull@
*/ /*@temp@
*/ ctbase p_c
) /*@
*/ ;
294 static bool ctbase_isStruct
(/*@notnull@
*/ /*@temp@
*/ ctbase p_c
) /*@
*/ ;
295 static
/*@observer@
*/ cstring ctbase_enumTag
(/*@notnull@
*/ ctbase p_ct
) /*@
*/ ;
297 static
/*@out@
*/ /*@notnull@
*/ /*@only@
*/ ctbase ctbase_new
(void
) /*@
*/ ;
298 static int nctbases
= 0;
300 static
/*@notnull@
*/ /*@only@
*/
301 ctbase ctbase_makeLiveFunction
(ctype p_b
, /*@only@
*/ uentryList p_p
);
304 static bool ctbase_isUnnamedSU
(ctbase c
)
306 return
(ctbase_isDefined
(c
)
307 && (ctbase_isStruct (c) || ctbase_isUnion (c))
308 && isFakeTag (c->contents.su->name));
310 # endif
/* DEADCODE
*/
312 static
/*@observer@
*/ ctbase ctbase_realType
(ctbase c
)
316 typeId uid
= ctbase_typeId
(c
);
318 if
(usymtab_isBoolType
(uid
))
320 return ctbase_getBool
();
324 ctbase ret
= ctype_getCtbase
325 (uentry_getRealType
(usymtab_getTypeEntry
(ctbase_typeId
(c
))));
327 llassert
(ret
!= ctbase_undefined
);
338 ctbase_isVoidPointer
(/*@dependent@
*/ /*@notnull@
*/ ctbase c
)
340 ctbase r
= ctbase_realType
(c
);
342 return
(ctbase_isKind
(r
, CT_PTR
) &&
343 ctype_isVoid
(r-
>contents.base
));
347 ctbase_isPointer
(/*@notnull@
*/ /*@dependent@
*/ ctbase c
)
349 ctbase r
= ctbase_realType
(c
);
351 return
(ctbase_isKind
(r
, CT_PTR
));
355 ctbase_isEitherArray
(/*@notnull@
*/ ctbase c
)
357 ctbase r
= ctbase_realType
(c
);
359 return
(ctbase_isKind
(r
, CT_ARRAY
)
360 || ctbase_isKind
(r
, CT_FIXEDARRAY
));
364 ctbase_isFixedArray
(/*@notnull@
*/ ctbase c
)
366 ctbase r
= ctbase_realType
(c
);
368 return
(ctbase_isKind
(r
, CT_FIXEDARRAY
));
372 ctbase_isStruct
(/*@notnull@
*/ ctbase c
)
374 ctbase r
= ctbase_realType
(c
);
376 return
(ctbase_isKind
(r
, CT_STRUCT
));
380 ctbase_isUnion
(/*@notnull@
*/ ctbase c
)
382 ctbase r
= ctbase_realType
(c
);
384 return
(ctbase_isKind
(r
, CT_UNION
));
388 ** clean this up
-> typeTable should store ctype
393 ctbase_typeBaseUid
(ctbase c
)
397 if
(ctbase_isDefined
(c
))
403 return ctbase_typeBaseUid
(ctype_getCtbase
(c-
>contents.base
));
405 else if
(ct
== CT_USER || ct
== CT_ABST || ct
== CT_NUMABST
)
407 return c-
>contents.tid
;
409 else if
(ct
== CT_FIXEDARRAY
)
411 return ctbase_typeBaseUid
(ctype_getCtbase
(c-
>contents.farray-
>base
));
415 llcontbuglit
("ctbase_typeBaseUid: bad call");
416 return typeId_invalid
;
419 return typeId_invalid
;
423 ctbase_isBaseUA
(ctbase c
)
427 if
(ctbase_isDefined
(c
))
433 return ctbase_isBaseUA
(ctype_getCtbase
(c-
>contents.base
));
435 else if
(ct
== CT_FIXEDARRAY
)
437 return ctbase_isBaseUA
(ctype_getCtbase
(c-
>contents.farray-
>base
));
440 return
(ct
== CT_USER || ct
== CT_ABST || ct
== CT_NUMABST
);
447 ctbase_typeId
(ctbase c
)
451 return c-
>contents.tid
;
455 if
(ctbase_isConj
(c
))
457 if
(ctype_isUA
(ctbase_getConjA
(c
))) {
458 return ctbase_typeId
(ctype_getCtbase
(ctbase_getConjA
(c
)));
459 } else if
(ctype_isUA
(ctbase_getConjB
(c
))) {
460 return ctbase_typeId
(ctype_getCtbase
(ctbase_getConjB
(c
)));
462 llcontbug
(message
("ctbase_typeId: bad call: %q", ctbase_unparse
(c
)));
463 return typeId_invalid
;
468 llcontbug
(message
("ctbase_typeId: bad call: %q", ctbase_unparse
(c
)));
469 return typeId_invalid
;
474 static
/*@only@
*/ cstring
475 ctbase_unparse
(ctbase c
)
477 if
(ctbase_isUndefined
(c
)) {
478 return cstring_makeLiteral
("<<undef>>");
484 return cstring_makeLiteral
("?");
486 return cstring_copy
(context_printBoolName
());
488 return
(cprim_unparse
(c-
>contents.prim
));
492 return
(usymtab_getTypeEntryName
(c-
>contents.tid
));
494 return
(message
("<expf: %t>", c-
>contents.base
));
496 /* no spaces for multiple pointers
*/
498 if
(ctype_isPointer
(c-
>contents.base
))
500 return
(cstring_appendChar
(cstring_copy
(ctype_unparse
(c-
>contents.base
)), '
*'
));
504 return
(message
("%t *", c-
>contents.base
));
508 ** C prints out array declarations backwards
, if
509 ** base is an array need to print out in reverse order.
512 if
(ctype_isArray
(c-
>contents.farray-
>base
))
514 ctype base
= c-
>contents.farray-
>base
;
515 cstring res
= message
("[%d]", (int
) c-
>contents.farray-
>size
);
517 while
(ctype_isArray
(base
))
519 if
(ctype_isFixedArray
(base
))
521 res
= message
("%q[%d]",
522 res
, (int
) ctype_getArraySize
(base
));
526 res
= message
("%q[]", res
);
529 base
= ctype_baseArrayPtr
(base
);
532 return
(message
("%t %q", base
, res
));
536 return
(message
("%t [%d]",
537 c-
>contents.farray-
>base
,
538 (int
) c-
>contents.farray-
>size
));
541 if
(ctype_isArray
(c-
>contents.base
))
543 ctype base
= c-
>contents.base
;
544 cstring res
= cstring_makeLiteral
("[]");
546 while
(ctype_isArray
(base
))
548 if
(ctype_isFixedArray
(base
))
550 res
= message
("%q[%d]",
551 res
, (int
) ctype_getArraySize
(base
));
555 res
= message
("%q[]", res
);
558 base
= ctype_baseArrayPtr
(base
);
561 return
(message
("%t %q", base
, res
));
566 return
(message
("%t []", c-
>contents.base
));
569 return
(message
("[function (%q) returns %t]",
570 uentryList_unparseParams
(c-
>contents.fcn-
>params
),
571 c-
>contents.fcn-
>rval
));
573 if
(cstring_isDefined
(c-
>contents.su-
>name
) &&
574 !cstring_isEmpty
(c-
>contents.su-
>name
) &&
575 !isFakeTag
(c-
>contents.su-
>name
))
577 return
(message
("struct %s", c-
>contents.su-
>name
));
581 return
(message
("struct { %q }",
582 uentryList_unparseAbbrev
(c-
>contents.su-
>fields
)));
585 if
(cstring_isDefined
(c-
>contents.su-
>name
) &&
586 !cstring_isEmpty
(c-
>contents.su-
>name
) &&
587 !isFakeTag
(c-
>contents.su-
>name
))
589 return
(message
("union %s", c-
>contents.su-
>name
));
593 return
(message
("union { %q }",
594 uentryList_unparseAbbrev
(c-
>contents.su-
>fields
)));
597 if
(isFakeTag
(c-
>contents.cenum-
>tag
))
599 return
(message
("enum { %q }",
600 enumNameList_unparseBrief
(c-
>contents.cenum-
>members
)));
604 return
(message
("enum %s { %q }",
605 c-
>contents.cenum-
>tag
,
606 enumNameList_unparseBrief
(c-
>contents.cenum-
>members
)));
609 if
(ctbase_isAnytype
(c
))
611 return
(cstring_makeLiteral
("<any>"));
613 else if
(c-
>contents.conj-
>isExplicit || context_getFlag
(FLG_SHOWALLCONJS
))
615 if
(!ctype_isSimple
(c-
>contents.conj-
>a
) ||
616 !ctype_isSimple
(c-
>contents.conj-
>b
))
618 return
(message
("<%t> | <%t>", c-
>contents.conj-
>a
, c-
>contents.conj-
>b
));
622 return
(message
("%t | %t", c-
>contents.conj-
>a
, c-
>contents.conj-
>b
));
627 return
(cstring_copy
(ctype_unparse
(c-
>contents.conj-
>a
)));
634 static
/*@only@
*/ cstring
635 ctbase_unparseDeep
(ctbase c
)
637 if
(ctbase_isUndefined
(c
))
639 return cstring_makeLiteral
("<<undef>>");
645 return cstring_makeLiteral
("?");
647 return cstring_copy
(context_printBoolName
());
649 return
(cprim_unparse
(c-
>contents.prim
));
651 if
(cstring_isNonEmpty
(c-
>contents.cenum-
>tag
))
653 return
(message
("enum %s { %q }",
654 c-
>contents.cenum-
>tag
,
655 enumNameList_unparse
(c-
>contents.cenum-
>members
)));
659 return
(message
("enum { %q }",
660 enumNameList_unparse
(c-
>contents.cenum-
>members
)));
665 return
(usymtab_getTypeEntryName
(c-
>contents.tid
));
667 return
(message
("<expf: %t>", c-
>contents.base
));
669 return
(message
("%t *", c-
>contents.base
));
671 return
(message
("%t [%d]", c-
>contents.farray-
>base
,
672 (int
) c-
>contents.farray-
>size
));
674 return
(message
("%t []", c-
>contents.base
));
676 return
(message
("[function (%q) returns %t]",
677 uentryList_unparse
(c-
>contents.fcn-
>params
),
678 c-
>contents.fcn-
>rval
));
680 return
(message
("struct %s { ... } ", c-
>contents.su-
>name
));
682 return
(message
("union %s { ... }", c-
>contents.su-
>name
));
684 if
(ctbase_isAnytype
(c
))
686 return
(cstring_makeLiteral
("<any>"));
690 return
(message
("%t", c-
>contents.conj-
>a
));
698 static
/*@only@
*/ cstring
699 ctbase_unparseNotypes
(ctbase c
)
701 llassert
(ctbase_isDefined
(c
));
706 return cstring_makeLiteral
("?");
708 return cstring_copy
(context_printBoolName
());
710 return
(cprim_unparse
(c-
>contents.prim
));
712 if
(typeId_isInvalid
(c-
>contents.tid
))
714 return cstring_makeLiteral
("enum");
718 return
(message
("T#%d", c-
>contents.tid
));
721 return
(message
("uT#%d", c-
>contents.tid
));
723 return
(message
("aT#%d", c-
>contents.tid
));
725 return
(message
("nT#%d", c-
>contents.tid
));
727 return
(message
("<expf: %q >", ctbase_unparseNotypes
(ctype_getCtbase
(c-
>contents.base
))));
729 return
(message
("%q *", ctbase_unparseNotypes
(ctype_getCtbase
(c-
>contents.base
))));
731 return
(message
("%q []", ctbase_unparseNotypes
(ctype_getCtbase
(c-
>contents.base
))));
733 return
(message
("[function (%d) returns %q]", uentryList_size
(c-
>contents.fcn-
>params
),
734 ctbase_unparseNotypes
(ctype_getCtbase
(c-
>contents.fcn-
>rval
))));
736 return
(message
("struct %s", c-
>contents.su-
>name
));
738 return
(message
("union %s", c-
>contents.su-
>name
));
740 return
(message
("[enumlist]"));
742 if
(ctbase_isAnytype
(c
))
744 return
(cstring_makeLiteral
("<any>"));
748 return
(message
("%q/%q",
749 ctbase_unparseNotypes
(ctype_getCtbase
(c-
>contents.conj-
>a
)),
750 ctbase_unparseNotypes
(ctype_getCtbase
(c-
>contents.conj-
>b
))));
758 static
/*@only@
*/ cstring
759 ctbase_unparseDeclaration
(ctbase c
, /*@only@
*/ cstring name
) /*@
*/
761 if
(ctbase_isUndefined
(c
))
769 return
(message
("? %q", name
));
771 return
(message
("%s %q", context_printBoolName
(), name
));
773 return
(message
("%q %q", cprim_unparse
(c-
>contents.prim
), name
));
777 return
(message
("%q %q", usymtab_getTypeEntryName
(c-
>contents.tid
), name
));
779 llcontbuglit
("ctbase_unparseDeclaration: expfcn");
782 if
(ctype_isFunction
(c-
>contents.base
))
784 return ctbase_unparseDeclaration
(ctype_getCtbase
(c-
>contents.base
), name
);
788 cstring s
= cstring_prependChar
('
*'
, name
);
789 cstring ret
= ctbase_unparseDeclaration
(ctype_getCtbase
(c-
>contents.base
), s
);
794 return
(message
("%q[%d]",
795 ctbase_unparseDeclaration
(ctype_getCtbase
(c-
>contents.farray-
>base
), name
),
796 (int
) c-
>contents.farray-
>size
));
798 return
(message
("%q[]",
799 ctbase_unparseDeclaration
(ctype_getCtbase
(c-
>contents.base
), name
)));
802 cstring s
= message
("%q(%q)", name
,
803 uentryList_unparseParams
(c-
>contents.fcn-
>params
));
805 return
(ctbase_unparseDeclaration
806 (ctype_getCtbase
(c-
>contents.fcn-
>rval
), s
));
809 if
(cstring_isDefined
(c-
>contents.su-
>name
) &&
810 !cstring_isEmpty
(c-
>contents.su-
>name
) &&
811 !isFakeTag
(c-
>contents.su-
>name
))
813 return
(message
("struct %s %q", c-
>contents.su-
>name
, name
));
817 return
(message
("struct { %q } %q",
818 uentryList_unparseAbbrev
(c-
>contents.su-
>fields
),
822 if
(cstring_isDefined
(c-
>contents.su-
>name
) &&
823 !cstring_isEmpty
(c-
>contents.su-
>name
) &&
824 !isFakeTag
(c-
>contents.su-
>name
))
826 return
(message
("union %s %q", c-
>contents.su-
>name
, name
));
830 return
(message
("union { %q } %q",
831 uentryList_unparseAbbrev
(c-
>contents.su-
>fields
),
835 if
(isFakeTag
(c-
>contents.cenum-
>tag
))
837 return
(message
("enum { %q } %q",
838 enumNameList_unparseBrief
(c-
>contents.cenum-
>members
),
843 return
(message
("enum %s { %q } %q",
844 c-
>contents.cenum-
>tag
,
845 enumNameList_unparseBrief
(c-
>contents.cenum-
>members
),
849 if
(ctbase_isAnytype
(c
))
851 return
(message
("<any> %q", name
));
853 else if
(c-
>contents.conj-
>isExplicit || context_getFlag
(FLG_SHOWALLCONJS
))
855 if
(!ctype_isSimple
(c-
>contents.conj-
>a
) ||
856 !ctype_isSimple
(c-
>contents.conj-
>b
))
858 cstring name1
= cstring_copy
(name
);
863 ctbase_unparseDeclaration
864 (ctype_getCtbase
(c-
>contents.conj-
>a
), name1
),
865 ctbase_unparseDeclaration
866 (ctype_getCtbase
(c-
>contents.conj-
>b
), name
)));
870 cstring s1
= ctbase_unparseDeclaration
(ctype_getCtbase
(c-
>contents.conj-
>a
),
871 cstring_copy
(name
));
873 (message
("%q | %q", s1
,
874 ctbase_unparseDeclaration
(ctype_getCtbase
(c-
>contents.conj-
>b
),
881 return
(cstring_copy
(ctype_unparse
(c-
>contents.conj-
>a
)));
888 static ctbase ctbase_undump
(d_char
*c
) /*@requires maxRead
(*c
) >= 2 @
*/
898 return
(ctbase_undefined
);
900 return
(ctbase_createUnknown
());
902 return
(ctbase_createBool
());
904 res
= ctbase_createPrim
(cprim_fromInt
(reader_getInt
(c
)));
905 reader_checkChar
(c
, '|'
);
908 res
= ctbase_createUser
(typeId_fromInt
(reader_getInt
(c
)));
909 reader_checkChar
(c
, '|'
);
912 res
= ctbase_createAbstract
(typeId_fromInt
(reader_getInt
(c
)));
913 reader_checkChar
(c
, '|'
);
916 res
= ctbase_createNumAbstract
(typeId_fromInt
(reader_getInt
(c
)));
917 reader_checkChar
(c
, '|'
);
920 res
= ctbase_makePointer
(ctype_undump
(c
));
921 reader_checkChar
(c
, '|'
);
924 res
= ctbase_makeArray
(ctype_undump
(c
));
925 reader_checkChar
(c
, '|'
);
929 ctype ct
= ctype_undump
(c
);
932 reader_checkChar
(c
, '
/'
);
933 size
= size_fromInt
(reader_getInt
(c
));
934 reader_checkChar
(c
, '|'
);
935 return
(ctbase_makeFixedArray
(ct
, size
));
940 char
*lp
= strchr
(*c
, '
('
);
942 llassertfatal
(lp
!= NULL);
945 ct
= ctype_undump
(c
);
948 return
(ctbase_makeLiveFunction
(ct
, uentryList_undump
(c
)));
955 char
*lc
= strchr
(*c
, '
{'
);
957 llassert
(lc
!= NULL);
960 sname
= mstring_copy
(*c
);
968 i
= (unsigned
) atoi
(sname
+ 1);
973 fields
= uentryList_undumpFields
(c
, g_currentloc
);
975 ctb
= ctbase_createStruct
(cstring_fromCharsO
(sname
), fields
);
981 char
*lc
= strchr
(*c
, '
{'
);
983 llassert
(lc
!= NULL);
986 sname
= mstring_copy
(*c
);
987 llassert
(sname
!= NULL);
995 i
= (unsigned
) atoi
(sname
+ 1);
999 return
(ctbase_createUnion
(cstring_fromCharsO
(sname
),
1000 uentryList_undumpFields
(c
, g_currentloc
)));
1006 char
*lc
= strchr
(*c
, '
{'
);
1008 llassert
(lc
!= NULL);
1011 sname
= mstring_copy
(*c
);
1018 i
= (unsigned
) atoi
(sname
+ 1);
1022 ret
= ctbase_createEnum
(cstring_fromCharsO
(sname
),
1023 enumNameList_undump
(c
));
1031 isExplicit
= bool_fromInt
(reader_getInt
(c
));
1032 reader_checkChar
(c
, '.'
);
1033 c1
= ctype_undump
(c
);
1034 reader_checkChar
(c
, '
/'
);
1035 c2
= ctype_undump
(c
);
1036 reader_checkChar
(c
, '|'
);
1038 return
(ctbase_makeConj
(c1
, c2
, isExplicit
));
1043 llerror
(FLG_SYNTAX
,
1044 message
("Bad Library line (type): %s", cstring_fromChars
(*c
)));
1046 /*drl bee
: pbr
*/ while
(**c
!= '\
0'
)
1051 return ctbase_createUnknown
();
1055 /* first letter of c encodes type
: */
1071 static
/*@only@
*/ cstring
1072 ctbase_dump
(ctbase c
)
1074 if
(!ctbase_isDefined
(c
))
1076 return cstring_makeLiteral
("?");
1082 return cstring_makeLiteral
("u");
1084 return cstring_makeLiteral
("b");
1086 return
(message
("p%d|", c-
>contents.prim
));
1088 return
(message
("s%d|", usymtab_convertTypeId
(c-
>contents.tid
)));
1090 return
(message
("a%d|", usymtab_convertTypeId
(c-
>contents.tid
)));
1092 return
(message
("n%d|", usymtab_convertTypeId
(c-
>contents.tid
)));
1094 return
(message
("t%q|", ctype_dump
(c-
>contents.base
)));
1096 return
(message
("y%q|", ctype_dump
(c-
>contents.base
)));
1098 return
(message
("F%q/%d|",
1099 ctype_dump
(c-
>contents.farray-
>base
),
1100 (int
) c-
>contents.farray-
>size
));
1102 DPRINTF
(("Dump function: %s", ctbase_unparse
(c
)));
1103 return
(message
("f%q (%q)", ctype_dump
(c-
>contents.fcn-
>rval
),
1104 uentryList_dumpParams
(c-
>contents.fcn-
>params
)));
1106 return
(message
("S%s{%q}", c-
>contents.su-
>name
,
1107 uentryList_dumpFields
(c-
>contents.su-
>fields
)));
1109 return
(message
("U%s{%q}", c-
>contents.su-
>name
,
1110 uentryList_dumpFields
(c-
>contents.su-
>fields
)));
1115 if
(cstring_isNonEmpty
(c-
>contents.cenum-
>tag
))
1117 s
= message
("e%s{%q}",
1118 c-
>contents.cenum-
>tag
,
1119 enumNameList_dump
(c-
>contents.cenum-
>members
));
1123 s
= message
("e{%q}",
1124 enumNameList_dump
(c-
>contents.cenum-
>members
));
1129 return
(message
("C%d.%q/%q|",
1130 bool_toInt
(c-
>contents.conj-
>isExplicit
),
1131 ctype_dump
(c-
>contents.conj-
>a
),
1132 ctype_dump
(c-
>contents.conj-
>b
)));
1134 /* should clean them up
! */
1135 return
(cstring_makeLiteral
("?"));
1137 llcontbug
(message
("Cannot dump: %q", ctbase_unparse
(c
)));
1138 return
(message
("u"));
1146 static
/*@only@
*/ ctbase
1147 ctbase_copy
(/*@notnull@
*/ ctbase c
)
1152 return
(ctbase_createUnknown
());
1154 return
(ctbase_createBool
());
1156 return
(ctbase_createEnum
(cstring_copy
(c-
>contents.cenum-
>tag
),
1157 enumNameList_copy
(c-
>contents.cenum-
>members
)));
1159 return
(ctbase_createPrim
(c-
>contents.prim
));
1161 return
(ctbase_createUser
(c-
>contents.tid
));
1163 return
(ctbase_createAbstract
(c-
>contents.tid
));
1165 return
(ctbase_createNumAbstract
(c-
>contents.tid
));
1167 return
(ctbase_expectFunction
(c-
>contents.base
));
1169 return
(ctbase_makePointer
(c-
>contents.base
));
1171 return
(ctbase_makeArray
(c-
>contents.base
));
1173 return
(ctbase_makeLiveFunction
(c-
>contents.fcn-
>rval
,
1174 uentryList_copy
(c-
>contents.fcn-
>params
)));
1176 return
(ctbase_createStruct
(cstring_copy
(c-
>contents.su-
>name
),
1177 uentryList_copy
(c-
>contents.su-
>fields
)));
1179 return
(ctbase_createUnion
(cstring_copy
(c-
>contents.su-
>name
),
1180 uentryList_copy
(c-
>contents.su-
>fields
)));
1182 /*@i@
*/ return
(c
); /* not a real copy for conj's
*/
1184 llbug
(message
("ctbase_copy: %q", ctbase_unparse
(c
)));
1192 ctbase_elist
(ctbase c
)
1194 llassert
(ctbase_isDefined
(c
));
1195 llassert
(c-
>type
== CT_ENUM
);
1197 return
(c-
>contents.cenum-
>members
);
1201 ctbase_free
(/*@only@
*/ ctbase c
)
1203 if
(c
== ctbase_bool || c
== ctbase_unknown
)
1205 /*@
-mustfree@
*/ return
; /*@
=mustfree@
*/
1211 if
(ctbase_isDefined
(c
))
1238 /* Cannot free params
: uentryList_free
(c-
>contents.fcn-
>params
); */
1239 uentryList_freeShallow
(c-
>contents.fcn-
>params
);
1244 cstring_free
(c-
>contents.su-
>name
);
1245 uentryList_free
(c-
>contents.su-
>fields
);
1249 /* Don't bree conj's
, */
1259 ** c should be
* <unknown
>
1262 static
/*@only@
*/ ctbase
1263 ctbase_expectFunction
(ctype c
)
1265 ctbase f
= ctbase_new
();
1267 f-
>type
= CT_EXPFCN
;
1268 f-
>contents.base
= c
;
1274 ctbase_isExpectFunction
(/*@notnull@
*/ ctbase ct
) /*@
*/
1276 return
(ct-
>type
== CT_EXPFCN
);
1280 ctbase_getExpectFunction
(/*@notnull@
*/ ctbase ct
)
1282 llassert
(ctbase_isExpectFunction
(ct
));
1283 return ct-
>contents.base
;
1287 ctbase_genMatch
(ctbase c1
, ctbase c2
, bool force
, bool arg
, bool def
, bool deep
)
1291 /* undefined types never match
*/
1293 if
(ctbase_isUndefined
(c1
) || ctbase_isUndefined
(c2
))
1296 /* abstract types match user types of same name
*/
1298 c1
= ctbase_realType
(c1
);
1299 c2
= ctbase_realType
(c2
);
1301 DPRINTF
(("Matching: %s / %s", ctbase_unparse
(c1
),
1302 ctbase_unparse
(c2
)));
1307 if
(c1tid
== CT_CONJ
)
1309 return
(ctbase_genMatch
(ctype_getCtbase
(c1-
>contents.conj-
>a
), c2
,
1310 force
, arg
, def
, deep
)
1311 || ctbase_genMatch
(ctype_getCtbase
(c1-
>contents.conj-
>b
), c2
,
1312 force
, arg
, def
, deep
));
1315 if
(c2tid
== CT_CONJ
)
1317 return
(ctbase_genMatch
(c1
, ctype_getCtbase
(c2-
>contents.conj-
>a
),
1318 force
, arg
, def
, deep
)
1319 || ctbase_genMatch
(c1
, ctype_getCtbase
(c2-
>contents.conj-
>b
),
1320 force
, arg
, def
, deep
));
1324 ** if the types don't match
, there are some special cases...
1329 /* unknowns match anything
*/
1331 if
(c1tid
== CT_UNKNOWN || c2tid
== CT_UNKNOWN
)
1336 if
(c1tid
== CT_FIXEDARRAY
1337 && (c2tid == CT_ARRAY || (!def && c2tid == CT_PTR)))
1339 if
(ctype_isVoid
(c2-
>contents.base
))
1341 return
(context_getFlag
(FLG_ABSTVOIDP
) ||
1342 (!(ctype_isRealAbstract
(c1-
>contents.farray-
>base
)) &&
1343 !(ctype_isRealAbstract
(c2-
>contents.base
))));
1346 return
(ctbase_genMatch
(ctype_getCtbase
(c1-
>contents.farray-
>base
),
1347 ctype_getCtbase
(c2-
>contents.base
),
1348 force
, arg
, def
, deep
));
1352 if
(c2tid
== CT_FIXEDARRAY
1353 && (c1tid == CT_ARRAY || (!def && c1tid == CT_PTR)))
1355 if
(ctype_isVoid
(c1-
>contents.base
))
1357 return
(context_getFlag
(FLG_ABSTVOIDP
) ||
1358 (!(ctype_isRealAbstract
(c2-
>contents.farray-
>base
)) &&
1359 !(ctype_isRealAbstract
(c1-
>contents.base
))));
1362 return
(ctbase_genMatch
(ctype_getCtbase
(c1-
>contents.base
),
1363 ctype_getCtbase
(c2-
>contents.farray-
>base
),
1364 force
, arg
, def
, deep
));
1367 /* evs
2000-07-25: Bool's may match user
/abstract types
*/
1369 if
((c1tid
== CT_BOOL
1370 && (c2tid == CT_PRIM && cprim_isInt (c2->contents.prim))) ||
1372 && (c1tid == CT_PRIM && cprim_isInt (c1->contents.prim))))
1374 return
(context_msgBoolInt
());
1377 if
((c1tid
== CT_BOOL
&& (ctuid_isAnyUserType (c2tid)))) {
1378 ctype t2c
= c2-
>contents.base
;
1379 return
(ctype_isBool
(t2c
));
1382 if
((c2tid
== CT_BOOL
&& (ctuid_isAnyUserType (c1tid)))) {
1383 ctype t1c
= c1-
>contents.base
;
1385 return
(ctype_isBool
(t1c
));
1388 if
((c1tid
== CT_ENUM
1389 && (c2tid == CT_PRIM && cprim_isInt (c2->contents.prim))) ||
1391 && (c1tid == CT_PRIM && cprim_isInt (c1->contents.prim))))
1393 return
(context_msgEnumInt
());
1397 ** arrays and pointers...yuk
!
1399 ** Considered equivalent except in definitions.
1400 ** (e.g.
, function parameters are equivalent
)
1406 if
(ctuid_isAP
(c1tid
) && ctuid_isAP (c2tid))
1413 ** Function pointers can be removed.
1415 ** [function ..
] is equivalent to
[function ..
] *
1418 if
(c1tid
== CT_PTR
&& c2tid == CT_FCN)
1420 if
(ctype_isFunction
(ctype_realType
(c1-
>contents.base
)))
1422 c1
= ctbase_realType
(ctype_getCtbaseSafe
(c1-
>contents.base
));
1427 if
(c2tid
== CT_PTR
&& c1tid == CT_FCN)
1429 if
(ctype_isFunction
(ctype_realType
(c2-
>contents.base
)))
1431 c2
= ctbase_realType
(ctype_getCtbaseSafe
(c2-
>contents.base
));
1437 ** we allow forward declarations to structures like
,
1439 ** typedef struct _t
*t
;
1442 ** struct _t
* to match t
1445 if
(context_getFlag
(FLG_FORWARDDECL
))
1447 if
(ctuid_isAnyUserType
(c1tid
))
1449 if
(ctuid_isAP
(c2tid
))
1451 ctype ts
= c2-
>contents.base
;
1453 if
(ctype_isUA
(ts
))
1455 typeId ttid
= ctype_typeId
(ts
);
1456 typeId ctid
= c1-
>contents.tid
;
1458 if
(usymtab_matchForwardStruct
(ctid
, ttid
))
1466 if
(ctuid_isAnyUserType
(c2tid
))
1468 if
(ctuid_isAP
(c1tid
))
1470 ctype ts
= c1-
>contents.base
;
1472 if
(ctype_isUA
(ts
))
1474 typeId ttid
= ctype_typeId
(ts
);
1475 typeId ctid
= c2-
>contents.tid
;
1477 if
(usymtab_matchForwardStruct
(ctid
, ttid
))
1496 return
(cprim_closeEnoughDeep
(c1-
>contents.prim
, c2-
>contents.prim
));
1498 return
(cprim_closeEnough
(c1-
>contents.prim
, c2-
>contents.prim
));
1505 return
(typeId_equal
(c1-
>contents.tid
, c2-
>contents.tid
));
1507 return
(cstring_equal
(c1-
>contents.cenum-
>tag
, c2-
>contents.cenum-
>tag
));
1509 if
(ctype_isVoid
(c1-
>contents.base
)
1510 ||
(ctype_isVoid
(c2-
>contents.base
)))
1512 if
(ctype_isFunction
(ctype_realType
(c1-
>contents.base
))
1513 || ctype_isFunction
(ctype_realType
(c2-
>contents.base
)))
1515 return
(!context_getFlag
(FLG_CASTFCNPTR
));
1519 return
(context_getFlag
(FLG_ABSTVOIDP
) ||
1520 (!(ctype_isRealAbstract
(c1-
>contents.base
)) &&
1521 !(ctype_isRealAbstract
(c2-
>contents.base
))));
1526 /* Only allow one implicit function pointer.
*/
1528 if
(!bool_equal
(ctype_isRealPointer
(c1-
>contents.base
),
1529 ctype_isRealPointer
(c2-
>contents.base
))
1530 && (ctype_isRealFunction (c1->contents.base)
1531 || ctype_isRealFunction
(c2-
>contents.base
)))
1536 return
(ctype_genMatch
(c1-
>contents.base
,
1537 c2-
>contents.base
, force
, arg
, def
, TRUE));
1540 if
(ctype_isVoid
(c1-
>contents.farray-
>base
)
1541 || ctype_isVoid
(c2-
>contents.farray-
>base
))
1543 return
(ctype_genMatch
(c1-
>contents.farray-
>base
,
1544 c2-
>contents.farray-
>base
,
1545 force
, arg
, def
, deep
));
1547 if
(ctype_isVoid
(c1-
>contents.base
) || ctype_isVoid
(c2-
>contents.base
))
1549 return
(ctype_genMatch
(c1-
>contents.base
, c2-
>contents.base
, force
, arg
, def
, TRUE));
1551 return
(ctype_genMatch
(c1-
>contents.fcn-
>rval
,
1552 c2-
>contents.fcn-
>rval
,
1553 force
, arg
, def
, TRUE)
1554 && uentryList_matchParams (c1->contents.fcn->params,
1555 c2-
>contents.fcn-
>params
,
1559 DPRINTF
(("Struct: %s / %s",
1560 c1-
>contents.su-
>name
,
1561 c2-
>contents.su-
>name
));
1563 if
(isFakeTag
(c1-
>contents.su-
>name
)
1564 && isFakeTag (c2->contents.su->name))
1566 /* Both fake tags
, check structure
*/
1567 if
(cstring_equal
(c1-
>contents.su-
>name
, c2-
>contents.su-
>name
))
1573 return uentryList_matchFields
(c1-
>contents.su-
>fields
,
1574 c2-
>contents.su-
>fields
);
1579 if
(!cstring_isEmpty
(c1-
>contents.su-
>name
))
1581 return
(cstring_equal
(c1-
>contents.su-
>name
, c2-
>contents.su-
>name
));
1585 if
(!cstring_isEmpty
(c2-
>contents.su-
>name
))
1590 llcontbuglit
("ctbase_genMatch: match fields");
1595 llcontbug
(message
("ctbase_genMatch: unknown type: %d\n", (int
)c1tid
));
1601 ** like ctbase_match
, except for conjuncts
:
1602 ** modifies conjuncts to match only
1606 ctbase_forceMatch
(ctbase c1
, ctbase c2
) /*@modifies c1
, c2@
*/
1608 return
(ctbase_genMatch
(c1
, c2
, TRUE, FALSE, FALSE, FALSE));
1612 ctbase_match
(ctbase c1
, ctbase c2
) /*@modifies nothing@
*/
1614 return
(ctbase_genMatch
(c1
, c2
, FALSE, FALSE, FALSE, FALSE));
1618 ctbase_matchDef
(ctbase c1
, ctbase c2
) /*@modifies nothing@
*/
1620 return
(ctbase_genMatch
(c1
, c2
, FALSE, FALSE, TRUE, FALSE));
1624 ctbase_matchArg
(ctbase c1
, ctbase c2
)
1626 return
(ctbase_genMatch
(c1
, c2
, FALSE, TRUE, FALSE, FALSE));
1629 static
/*@out@
*/ /*@only@
*/ /*@notnull@
*/ ctbase
1632 ctbase c
= (ctbase
) dmalloc
(sizeof
(*c
));
1636 if
(nctbases
% 100 == 0 && nctbases > lastnc)
1638 llmsg
(message
("ctbases: %d", nctbases
));
1645 static
/*@only@
*/ ctbase
1646 ctbase_createPrim
(cprim p
)
1648 ctbase c
= ctbase_new
();
1651 c-
>contents.prim
= p
;
1656 static
/*@observer@
*/ ctbase
1657 ctbase_getBool
(void
)
1659 /*@i@
*/ return ctbase_createBool
();
1663 ctbase_createBool
(void
)
1665 if
(!ctbase_isDefined
(ctbase_bool
))
1667 ctbase_bool
= ctbase_new
();
1668 ctbase_bool-
>type
= CT_BOOL
;
1669 ctbase_bool-
>contents.prim
= CTX_BOOL
;
1672 /*@
-retalias@
*/ /*@
-globstate@
*/
1674 /*@
=retalias@
*/ /*@
=globstate@
*/
1677 static
/*@only@
*/ ctbase
1678 ctbase_createUser
(typeId u
)
1680 ctbase c
= ctbase_new
();
1683 c-
>contents.tid
= u
;
1685 llassert
(typeId_isValid
(u
));
1690 static
/*@only@
*/ ctbase
1691 ctbase_createEnum
(/*@keep@
*/ cstring etag
, /*@keep@
*/ enumNameList emembers
)
1693 ctbase c
= ctbase_new
();
1697 if
(cstring_isUndefined
(etag
))
1699 llcontbuglit
("Undefined enum tag!");
1703 c-
>contents.cenum
= (tenum
) dmalloc
(sizeof
(*c-
>contents.cenum
));
1704 c-
>contents.cenum-
>tag
= etag
;
1705 c-
>contents.cenum-
>members
= emembers
;
1710 static
/*@observer@
*/ cstring
1711 ctbase_enumTag
(/*@notnull@
*/ ctbase ct
)
1713 return
(ct-
>contents.cenum-
>tag
);
1716 static
/*@only@
*/ ctbase
1717 ctbase_createAbstract
(typeId u
)
1719 ctbase c
= ctbase_new
();
1722 c-
>contents.tid
= u
;
1724 /* also check its abstract?
*/
1726 llassert
(typeId_isValid
(c-
>contents.tid
));
1731 static
/*@only@
*/ ctbase
1732 ctbase_createNumAbstract
(typeId u
)
1734 ctbase c
= ctbase_new
();
1736 c-
>type
= CT_NUMABST
;
1737 c-
>contents.tid
= u
;
1739 /* also check its abstract?
*/
1741 llassert
(typeId_isValid
(c-
>contents.tid
));
1745 static
/*@only@
*/ ctbase
1746 ctbase_createUnknown
(void
)
1748 if
(!ctbase_isDefined
(ctbase_unknown
))
1750 ctbase_unknown
= ctbase_new
();
1751 ctbase_unknown-
>type
= CT_UNKNOWN
;
1752 ctbase_unknown-
>contents.prim
= CTX_UNKNOWN
;
1755 /*@
-retalias@
*/ /*@
-globstate@
*/
1756 return ctbase_unknown
;
1757 /*@
=retalias@
*/ /*@
=globstate@
*/
1761 ** requires
: result is not assigned to b
1762 ** (should copy
, but no way to reclaim storage
)
1765 static
/*@only@
*/ ctbase
1766 ctbase_makePointer
(ctype b
)
1768 ctbase c
= ctbase_new
();
1771 c-
>contents.base
= b
;
1776 static
/*@only@
*/ ctbase
1777 ctbase_makeArray
(ctype b
)
1779 ctbase c
= ctbase_new
();
1782 c-
>contents.base
= b
;
1787 static
/*@notnull@
*/ /*@only@
*/ ctbase
1788 ctbase_makeFixedArray
(ctype b
, size_t size
)
1790 ctbase c
= ctbase_new
();
1792 c-
>type
= CT_FIXEDARRAY
;
1794 c-
>contents.farray
= (tfixed
) dmalloc
(sizeof
(*c-
>contents.farray
));
1795 c-
>contents.farray-
>base
= b
;
1796 c-
>contents.farray-
>size
= size
;
1802 ctbase_makeFunction
(ctype b
, /*@only@
*/ uentryList p
)
1804 ctbase c
= ctbase_new
();
1808 c-
>contents.fcn
= (cfcn
) dmalloc
(sizeof
(*c-
>contents.fcn
));
1810 if
(ctype_isFunction
(b
)) /* was
: && ctype_isPointer (b)) */
1815 if
(ctype_isPointer
(b
))
1817 ctb
= ctype_getCtbase
(ctype_baseArrayPtr
(b
));
1821 ctb
= ctype_getCtbase
(b
);
1824 llassert
(ctbase_isDefined
(ctb
));
1825 llassert
(ctb-
>type
== CT_FCN
);
1827 rval
= ctype_makeFunction
(ctb-
>contents.fcn-
>rval
, p
);
1829 c-
>contents.fcn-
>rval
= rval
;
1830 c-
>contents.fcn-
>params
= uentryList_copy
(ctb-
>contents.fcn-
>params
); /* no copy before
*/
1834 c-
>contents.fcn-
>rval
= b
;
1835 c-
>contents.fcn-
>params
= uentryList_copy
(p
); /* no copy before
*/
1836 /*@
-branchstate@
*/ /* p is really released on this branch
*/
1840 ct
= cttable_addComplex
(c
);
1841 return
(ct
); /* was
: ctype_makePointer
(ct
)); */
1845 ctbase_makeNFFunction
(ctype b
, /*@only@
*/ uentryList p
)
1847 ctbase c
= ctbase_new
();
1851 c-
>contents.fcn
= (cfcn
) dmalloc
(sizeof
(*c-
>contents.fcn
));
1853 if
(ctype_isFunction
(b
)) /* was
&& ctype_isPointer (b)) */
1858 if
(ctype_isPointer
(b
))
1860 ctb
= ctype_getCtbase
(ctype_baseArrayPtr
(b
));
1864 ctb
= ctype_getCtbase
(b
);
1867 llassert
(ctbase_isDefined
(ctb
));
1868 llassert
(ctb-
>type
== CT_FCN
);
1870 rval
= ctype_makeNFParamsFunction
(ctb-
>contents.fcn-
>rval
, p
);
1872 c-
>contents.fcn-
>rval
= rval
;
1873 c-
>contents.fcn-
>params
= uentryList_copy
(ctb-
>contents.fcn-
>params
);
1877 c-
>contents.fcn-
>rval
= b
;
1878 c-
>contents.fcn-
>params
= uentryList_copy
(p
);
1883 ct
= cttable_addComplex
(c
);
1884 return
(ct
); /* was
: ctype_makePointer
(ct
)); */
1887 static
/*@only@
*/ ctbase
1888 ctbase_makeLiveFunction
(ctype b
, /*@only@
*/ uentryList p
)
1890 ctbase c
= ctbase_new
();
1894 c-
>contents.fcn
= (cfcn
) dmalloc
(sizeof
(*c-
>contents.fcn
));
1895 c-
>contents.fcn-
>rval
= b
;
1896 c-
>contents.fcn-
>params
= p
;
1898 /*@
-mustfree@
*/ return
(c
); /*@
=mustfree@
*/
1901 static
/*@observer@
*/ /*@notnull@
*/ ctbase
1902 ctbase_realFunction
(/*@dependent@
*/ /*@notnull@
*/ ctbase c
)
1906 if
(c-
>type
== CT_FCN
)
1911 llassert
(ctbase_isFunction
(c
));
1913 res
= ctype_getCtbase
(c-
>contents.base
);
1915 llassert
(ctbase_isDefined
(res
));
1921 ctbase_isFunction
(ctbase c
)
1923 llassert
(c
!= ctbase_undefined
);
1925 if
(c-
>type
== CT_FCN
)
1931 if
(c-
>type
== CT_PTR
)
1933 ctbase fcn
= ctype_getCtbase
(ctbase_baseArrayPtr
(c
));
1935 return
(ctbase_isDefined
(fcn
) && fcn->type == CT_FCN);
1942 /* doesn't copy c1 and c2
*/
1944 static
/*@only@
*/ ctbase
1945 ctbase_makeConj
(ctype c1
, ctype c2
, bool isExplicit
)
1947 ctbase c
= ctbase_new
();
1951 c-
>contents.conj
= (tconj
) dmalloc
(sizeof
(*c-
>contents.conj
));
1952 c-
>contents.conj-
>a
= c1
;
1953 c-
>contents.conj-
>b
= c2
;
1954 c-
>contents.conj-
>isExplicit
= isExplicit
;
1959 static bool ctbase_isAnytype
(/*@notnull@
*/ ctbase b
)
1962 ** A unknown|dne conj is a special representation for an anytype.
1965 if
(b-
>type
== CT_CONJ
)
1968 return
(b-
>contents.conj-
>a
== ctype_unknown
1969 && b->contents.conj->b == ctype_dne);
1970 /*@noaccess ctype@
*/
1977 ctbase_getConjA
(/*@notnull@
*/ ctbase c
)
1979 llassert
(c-
>type
== CT_CONJ
);
1980 return
(c-
>contents.conj-
>a
);
1984 ctbase_getConjB
(/*@notnull@
*/ ctbase c
)
1986 llassert
(c-
>type
== CT_CONJ
);
1987 return
(c-
>contents.conj-
>b
);
1991 ctbase_isExplicitConj
(/*@notnull@
*/ ctbase c
)
1993 llassert
(c-
>type
== CT_CONJ
);
1994 return
(c-
>contents.conj-
>isExplicit
);
1997 static
/*@only@
*/ ctbase
1998 ctbase_createStruct
(/*@only@
*/ cstring n
, /*@only@
*/ uentryList f
)
2000 ctbase c
= ctbase_new
();
2002 c-
>type
= CT_STRUCT
;
2004 c-
>contents.su
= (tsu
) dmalloc
(sizeof
(*c-
>contents.su
));
2005 c-
>contents.su-
>name
= n
;
2006 c-
>contents.su-
>fields
= f
;
2011 static
/*@observer@
*/ uentryList
2012 ctbase_getuentryList
(/*@notnull@
*/ ctbase c
)
2014 c
= ctbase_realType
(c
);
2016 if
(!(c-
>type
== CT_STRUCT || c-
>type
== CT_UNION
))
2017 llfatalbug
(message
("ctbase_getuentryList: bad invocation: %q", ctbase_unparse
(c
)));
2019 return
(c-
>contents.su-
>fields
);
2023 ctbase_createUnion
(/*@keep@
*/ cstring n
, /*@only@
*/ uentryList f
)
2025 ctbase c
= ctbase_new
();
2029 c-
>contents.su
= (tsu
) dmalloc
(sizeof
(*c-
>contents.su
));
2030 c-
>contents.su-
>name
= n
;
2031 c-
>contents.su-
>fields
= f
;
2037 ctbase_baseArrayPtr
(/*@notnull@
*/ ctbase c
)
2040 c
= ctbase_realType
(c
);
2043 if
(ct
== CT_FIXEDARRAY
)
2045 return c-
>contents.farray-
>base
;
2049 llassert
(ctuid_isAP
(ct
));
2051 return c-
>contents.base
;
2056 ctbase_baseFunction
(/*@notnull@
*/ ctbase c
)
2059 c
= ctbase_realFunction
(c
);
2061 if
(c-
>type
!= CT_FCN
)
2063 llfatalbug
(message
("ctbase_baseFunction: bad call: %q", ctbase_unparse
(c
)));
2066 return
(c-
>contents.fcn-
>rval
);
2070 ctbase_argsFunction
(/*@notnull@
*/ ctbase c
)
2073 c
= ctbase_realFunction
(c
);
2075 if
(c-
>type
!= CT_FCN
)
2077 llfatalbug
(message
("ctbase_argsFunction: bad call: %q",
2078 ctbase_unparse
(c
)));
2080 return
(c-
>contents.fcn-
>params
);
2084 ctbase_baseisExpFcn
(ctype c
)
2087 c
= ctype_removePointers
(c
);
2089 cb
= ctype_getCtbase
(c
);
2090 llassert
(ctbase_isDefined
(cb
));
2092 if
(cb-
>type
== CT_FCN
)
2094 c
= ctype_removePointers
(ctype_getReturnType
(c
));
2096 cb
= ctype_getCtbase
(c
);
2097 llassert
(ctbase_isDefined
(cb
));
2099 return
(cb-
>type
== CT_EXPFCN
);
2105 ** ctbase_newBase behaves specially when p is a CONJ
:
2107 ** c
-> conj
(newBase
(c
, p.a
), p.b
)
2111 ctbase_newBase
(ctype c
, ctype p
)
2115 DPRINTF
(("New base: %s / %s", ctype_unparse
(c
), ctype_unparse
(p
)));
2117 if
(ctype_isUndefined
(c
) || ctype_isUnknown
(c
))
2122 cb
= ctype_getCtbase
(c
);
2124 if
(ctype_isConj
(p
))
2126 ctbase pb
= ctype_getCtbase
(p
);
2128 llassert
(ctbase_isDefined
(pb
));
2130 if
(pb-
>contents.conj-
>isExplicit
)
2132 return
(ctype_makeExplicitConj
(ctype_newBase
(c
, pb-
>contents.conj-
>a
),
2133 pb-
>contents.conj-
>b
));
2138 return
(ctype_makeConj
(ctype_newBase
(c
, pb-
>contents.conj-
>a
),
2139 pb-
>contents.conj-
>b
));
2144 if
(ctbase_baseisExpFcn
(c
))
2146 return
(ctbase_newBaseExpFcn
(c
, p
));
2149 llassert
(ctbase_isDefined
(cb
));
2169 cbn
= ctbase_newBase
(cb-
>contents.base
, p
);
2170 ret
= ctype_makePointer
(cbn
);
2175 return
(ctype_makeFixedArray
(ctbase_newBase
(cb-
>contents.farray-
>base
, p
),
2176 cb-
>contents.farray-
>size
));
2178 return
(ctype_makeArray
(ctbase_newBase
(cb-
>contents.base
, p
)));
2180 return
(ctype_makeRawFunction
(ctbase_newBase
(cb-
>contents.fcn-
>rval
, p
),
2181 cb-
>contents.fcn-
>params
));
2183 return
(ctype_makeConjAux
(ctbase_newBase
(cb-
>contents.conj-
>a
, p
),
2184 ctbase_newBase
(cb-
>contents.conj-
>b
, p
),
2185 cb-
>contents.conj-
>isExplicit
));
2187 llcontbug
(message
("ctbase_newBase: bad ctbase: %q", ctbase_unparse
(cb
)));
2194 ctbase_newBaseExpFcn
(ctype c
, ctype p
)
2196 ctbase cb
= ctype_getCtbase
(c
);
2199 ctype fp
= ctype_unknown
;
2200 uentryList ctargs
= ctype_argsFunction
(c
);
2203 ** okay
, this is really ugly...
2205 ** pointers inside
<expf
> mean pointers to the function
;
2206 ** pointers outside
<expf
> are pointers to the return value
;
2207 ** because its a function there is one superfluous pointer.
2211 ** bf is a ctype
, used to derived structure of cb
2214 if
(!ctbase_isFunction
(cb
))
2215 llbuglit
("ctbase_newBaseExpFcn: expFcn -> not a function");
2217 tmpct
= ctype_getBaseType
(ctype_getReturnType
(c
));
2220 ** pointers before expfcn
-> p are pointers to function
, not result
2224 tcb
= ctype_getCtbase
(tmpct
);
2226 llassert
(ctbase_isDefined
(tcb
));
2227 tmpct
= tcb-
>contents.base
;
2230 ** record pointers to base in fp
2233 while
(!ctype_isUnknown
(tmpct
))
2235 if
(ctype_isExpFcn
(tmpct
)) {
2236 ctbase ttcb
= ctype_getCtbase
(tmpct
);
2239 ** evs
2000-05-16: This is necessary to deal with function pointers in parens.
2240 ** The whole function pointer parsing is a major kludge
, but it seems to work
,
2241 ** and I'm only embarrassed by it when I haven't look at the C spec recently...
2244 llassert
(ctbase_isDefined
(ttcb
));
2245 tmpct
= ttcb-
>contents.base
;
2246 llassert
(!ctype_isUnknown
(tmpct
));
2249 switch
(ctype_getCtKind
(tmpct
))
2252 fp
= ctype_makePointer
(fp
);
2253 /*@switchbreak@
*/ break
;
2255 fp
= ctype_makeArray
(fp
);
2256 /*@switchbreak@
*/ break
;
2259 ctbase fbase
= ctype_getCtbase
(tmpct
);
2261 if
(ctbase_isFunction
(fbase
))
2263 fp
= ctype_makeFunction
(fp
, uentryList_copy
(ctargs
));
2264 ctargs
= ctbase_argsFunction
(fbase
);
2270 ("ctbase_newBaseExpFcn: fixing expfunction: bad complex type: %s [base: %q]",
2271 ctype_unparse
(tmpct
), ctbase_unparse
(fbase
)));
2278 (message
("ctbase_newBaseExpFcn: fixing expfunction: bad type: %s",
2279 ctype_unparse
(tmpct
)));
2283 tmpct
= ctype_baseArrayPtr
(tmpct
);
2287 tmpct
= ctype_getReturnType
(c
);
2290 ** pointers to expf are pointers to return value
2293 while
(!ctype_isExpFcn
(tmpct
))
2295 switch
(ctype_getCtKind
(tmpct
))
2298 p
= ctype_makePointer
(p
);
2299 /*@switchbreak@
*/ break
;
2301 p
= ctype_makeArray
(p
);
2302 /*@switchbreak@
*/ break
;
2305 ctbase fbase
= ctype_getCtbase
(tmpct
);
2307 if
(ctbase_isFunction
(fbase
))
2309 p
= ctype_makeFunction
(p
, uentryList_copy
(ctbase_argsFunction
(fbase
)));
2315 ("ctbase_newBaseExpFcn: fixing expfunction: bad complex type: %s",
2316 ctype_unparse
(tmpct
)));
2324 (message
("ctbase_newBaseExpFcn: fixing expfunction2: bad type: %t",
2329 tmpct
= ctype_baseArrayPtr
(tmpct
);
2335 ** pointers to fp are pointers to function type
2338 ret
= ctype_makeRawFunction
(p
, uentryList_copy
(ctargs
));
2340 while
(ctype_getCtKind
(fp
) > CTK_PLAIN
)
2342 switch
(ctype_getCtKind
(fp
))
2345 ret
= ctype_makePointer
(ret
);
2346 /*@switchbreak@
*/ break
;
2348 ret
= ctype_makeArray
(ret
);
2349 /*@switchbreak@
*/ break
;
2352 ctbase fbase
= ctype_getCtbase
(fp
);
2354 if
(ctbase_isFunction
(fbase
))
2357 ctype_makeFunction
(ret
,
2358 uentryList_copy
(ctbase_argsFunction
(fbase
)));
2369 llcontbug
(message
("post-fixing expfunction: bad type: %t", fp
));
2373 fp
= ctype_baseArrayPtr
(fp
);
2382 ** returns lowest level base of c
: plain type
2385 static
/*@notnull@
*/ /*@only@
*/ ctbase
2386 ctbase_getBaseType
(/*@notnull@
*/ ctbase c
)
2401 return
(ctbase_copy
(c
));
2405 return
(ctbase_getBaseType
(ctype_getCtbaseSafe
(c-
>contents.base
)));
2408 return
(ctbase_getBaseType
(ctype_getCtbaseSafe
(c-
>contents.farray-
>base
)));
2409 case CT_CONJ
: /* base type of A conj branch?
*/
2410 return
(ctbase_getBaseType
(ctype_getCtbaseSafe
(c-
>contents.conj-
>a
)));
2412 return
(ctbase_copy
(c
));
2415 llfatalbug
(message
("ctbase_getBaseType: bad ctbase: %q", ctbase_unparse
(c
)));
2423 ctbase_compare
(ctbase c1
, ctbase c2
, bool strict
)
2427 if
(ctbase_isUndefined
(c1
) || ctbase_isUndefined
(c2
))
2429 llcontbuglit
("ctbase_compare: undefined ctbase");
2446 return
(int_compare
(c1-
>contents.prim
, c2-
>contents.prim
));
2450 return
(typeId_compare
(c1-
>contents.tid
, c2-
>contents.tid
));
2453 case CT_ENUM
: /* for now
, keep like abstract
*/
2456 return
(typeId_compare
(c1-
>contents.tid
, c2-
>contents.tid
));
2458 return
(ctype_compare
(c1-
>contents.base
, c2-
>contents.base
));
2460 INTCOMPARERETURN
(c1-
>contents.farray-
>size
, c2-
>contents.farray-
>size
);
2462 return
(ctype_compare
(c1-
>contents.farray-
>base
,
2463 c2-
>contents.farray-
>base
));
2465 return
(ctype_compare
(c1-
>contents.base
, c2-
>contents.base
));
2468 COMPARERETURN
(ctype_compare
(c1-
>contents.fcn-
>rval
, c2-
>contents.fcn-
>rval
));
2472 return
(uentryList_compareStrict
(c1-
>contents.fcn-
>params
,
2473 c2-
>contents.fcn-
>params
));
2477 return
(uentryList_compareParams
(c1-
>contents.fcn-
>params
,
2478 c2-
>contents.fcn-
>params
));
2482 return
(ctype_compare
(c1-
>contents.base
, c2-
>contents.base
));
2485 /* evs
2000-07-28: this block was missing
! */
2487 int ncmp
= cstring_compare
(c1-
>contents.su-
>name
,
2488 c2-
>contents.su-
>name
);
2491 if
(isFakeTag
(c1-
>contents.su-
>name
)
2492 && isFakeTag (c2->contents.su->name)) {
2493 ; /* If they are both fake struct tags
, don't require match.
*/
2500 DPRINTF
(("Comparing fields: %s / %s",
2501 ctbase_unparse
(c1
),
2502 ctbase_unparse
(c2
)));
2504 return
(uentryList_compareFields
(c1-
>contents.su-
>fields
,
2505 c2-
>contents.su-
>fields
));
2508 COMPARERETURN
(ctype_compare
(c1-
>contents.conj-
>a
,
2509 c2-
>contents.conj-
>a
));
2510 COMPARERETURN
(ctype_compare
(c1-
>contents.conj-
>b
,
2511 c2-
>contents.conj-
>b
));
2512 return
(bool_compare
(c1-
>contents.conj-
>isExplicit
,
2513 c2-
>contents.conj-
>isExplicit
));
2520 ctbase_compareStrict
(/*@notnull@
*/ ctbase c1
, /*@notnull@
*/ ctbase c2
)
2522 return
(ctbase_compare
(c1
, c2
, TRUE));
2525 static bool ctbase_equivStrict
(/*@notnull@
*/ ctbase c1
, /*@notnull@
*/ ctbase c2
)
2527 return
(ctbase_compareStrict
(c1
,c2
) == 0);
2530 static bool ctbase_equiv
(/*@notnull@
*/ ctbase c1
, /*@notnull@
*/ ctbase c2
)
2532 return
(ctbase_compare
(c1
, c2
, FALSE) == 0);
2536 ctbase_isKind
(/*@notnull@
*/ ctbase c
, ctuid kind
)
2544 return
(ctbase_isKind
(ctype_getCtbaseSafe
(c-
>contents.conj-
>a
), kind
) ||
2545 ctbase_isKind
(ctype_getCtbaseSafe
(c-
>contents.conj-
>b
), kind
));
2552 ctbase_isKind2
(/*@notnull@
*/ ctbase c
, ctuid kind1
, ctuid kind2
)
2556 if
(ck
== kind1 || ck
== kind2
)
2560 return
(ctbase_isKind2
(ctype_getCtbaseSafe
(c-
>contents.conj-
>a
), kind1
, kind2
) ||
2561 ctbase_isKind2
(ctype_getCtbaseSafe
(c-
>contents.conj-
>b
), kind1
, kind2
));
2568 ctbase_isAbstract
(/*@notnull@
*/ ctbase c
)
2570 return
(c-
>type
== CT_ABST || c-
>type
== CT_NUMABST
);
2574 ctbase_isNumAbstract
(/*@notnull@
*/ ctbase c
)
2576 return
(c-
>type
== CT_NUMABST
);
2579 static bool ctbase_isUA
(ctbase c
)
2581 return
(ctbase_isDefined
(c
) && (ctuid_isAnyUserType (c->type)));
2585 ctbase_almostEqual
(ctbase c1
, ctbase c2
)
2589 /* undefined types never match
*/
2591 if
(ctbase_isUndefined
(c1
) || ctbase_isUndefined
(c2
))
2597 if
(c1tid
== CT_FIXEDARRAY
&& c2tid == CT_ARRAY)
2599 return
(ctbase_almostEqual
(ctype_getCtbase
(c1-
>contents.farray-
>base
),
2600 ctype_getCtbase
(c2-
>contents.base
)));
2603 if
(c2tid
== CT_FIXEDARRAY
&& c1tid == CT_ARRAY)
2605 return
(ctbase_almostEqual
(ctype_getCtbase
(c1-
>contents.base
),
2606 ctype_getCtbase
(c2-
>contents.farray-
>base
)));
2617 return
(cprim_equal
(c1-
>contents.prim
, c2-
>contents.prim
));
2623 return
(typeId_equal
(c1-
>contents.tid
, c2-
>contents.tid
));
2625 return
(cstring_equal
(c1-
>contents.cenum-
>tag
, c2-
>contents.cenum-
>tag
));
2627 return
(ctype_almostEqual
(c1-
>contents.base
, c2-
>contents.base
));
2629 return
(ctype_almostEqual
(c1-
>contents.farray-
>base
,
2630 c2-
>contents.farray-
>base
));
2632 return
(ctype_almostEqual
(c1-
>contents.base
, c2-
>contents.base
));
2634 return
(ctype_almostEqual
(c1-
>contents.fcn-
>rval
, c2-
>contents.fcn-
>rval
)
2635 && uentryList_matchParams (c1->contents.fcn->params,
2636 c2-
>contents.fcn-
>params
, FALSE, TRUE));
2639 if
(!cstring_isEmpty
(c1-
>contents.su-
>name
))
2641 return
(cstring_equal
(c1-
>contents.su-
>name
, c2-
>contents.su-
>name
));
2645 if
(!cstring_isEmpty
(c2-
>contents.su-
>name
))
2650 llcontbuglit
("ctbase_almostEqual: match fields");
2654 llcontbug
(message
("ctbase_almostEqual: unknown type: %d\n", (int
)c1tid
));
2659 /*drl added July
02, 001
2660 called by ctype_getArraySize
2663 static size_t ctbase_getArraySize
(ctbase ctb
)
2665 /*drl
1/25/2002 fixed discovered by Jim Francis
*/
2668 llassert
(ctbase_isDefined
(ctb
) );
2669 r
= ctbase_realType
(ctb
);
2670 llassert
(ctbase_isFixedArray
(r
) );
2672 return
(r-
>contents.farray-
>size
);
2675 static bool ctbase_isBigger
(ctbase ct1
, ctbase ct2
)
2677 if
(ct1
!= NULL && ct2 != NULL
2678 && (ct1->type == CT_PRIM && ct2->type == CT_PRIM))
2680 /* Only compare sizes for primitives
*/
2681 cprim cp1
= ct1-
>contents.prim
;
2682 cprim cp2
= ct2-
>contents.prim
;
2683 int nbits1
= cprim_getExpectedBits
(cp1
);
2684 int nbits2
= cprim_getExpectedBits
(cp2
);
2686 if
(nbits1
> nbits2
) {
2698 static int ctbase_getSize
(ctbase ct
)
2711 cprim cp
= ct-
>contents.prim
;
2712 int nbits
= cprim_getExpectedBits
(cp
);
2724 /* Malloc returns void
*, but they are bytes. Normal void
* is pointer size.
*/
2725 if
(ctype_isVoid
(ct-
>contents.base
))
2731 return ctype_getSize
(ct-
>contents.base
);