2 ** vim
: set syntax
=c filetype
=c shiftwidth
=2 softtabstop
=2 expandtab
:
4 ** Splint
- annotation-assisted static program checker
5 ** Copyright
(C
) 1994-2003 University of Virginia
,
6 ** Massachusetts Institute of Technology
8 ** This program is free software
; you can redistribute it and
/or modify it
9 ** under the terms of the GNU General Public License as published by the
10 ** Free Software Foundation
; either version
2 of the License
, or
(at your
11 ** option
) any later version.
13 ** This program is distributed in the hope that it will be useful
, but
14 ** WITHOUT
ANY WARRANTY
; without even the implied warranty of
15 ** MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU
16 ** General Public License for more details.
18 ** The GNU General Public License is available from http
://www.gnu.org
/ or
19 ** the Free Software Foundation
, Inc.
, 59 Temple Place
- Suite
330, Boston
,
20 ** MA
02111-1307, USA.
22 ** For information on splint
: splint@cs.virginia.edu
23 ** To report a bug
: splint-bug@cs.virginia.edu
24 ** For more information
: http
://www.splint.org
29 ** NOTE
: This is not a stand-alone source file
, but is included in ctype.c.
30 ** (This is necessary because there is no other way in C to have a
31 ** hidden scope
, besides at the file level.
)
36 abst_typedef
/*@null@
*/ struct s_ctbase
*ctbase
;
38 /*@function static bool ctuid_isAnyUserType
(sef ctuid p_cid
) @
*/
40 /*@
-macrofcndecl@
*/ /*@
-macroparams@
*/
41 # define ctuid_isAnyUserType
(cid
) \
42 ((cid
) == CT_ABST ||
(cid
) == CT_USER ||
(cid
) == CT_NUMABST
)
43 /*@
=macrofcndecl@
*/ /*@
=macroparams@
*/
45 /*:private
:*/ typedef struct
{
48 ctype base
; /* type I point to
(or element of array
) */
49 ctype ptr
; /* type of pointer to me
*/
50 ctype array
; /* type of array of me
*/
51 cstring unparse
; /* unparse me
, if memoized
*/
54 typedef
/*@only@
*/ ctentry o_ctentry
;
59 /*@relnull@
*/ /*@only@
*/ o_ctentry
*entries
;
60 /* memoize matches...maybe in context?
*/
63 extern bool ctentry_isBogus
(/*@sef@
*/ ctentry p_c
) /*@
*/;
64 # define ctentry_isBogus
(c
) \
65 ((c
)->kind
== CTK_INVALID ||
(c
)->kind
== CTK_DNE
)
67 static cttable cttab
= { 0, 0, NULL };
69 static
/*@notnull@
*/ /*@only@
*/ ctbase ctbase_createAbstract
(typeId p_u
);
70 static
/*@notnull@
*/ /*@only@
*/ ctbase ctbase_createNumAbstract
(typeId p_u
);
71 static
/*@observer@
*/ cstring ctentry_doUnparse
(ctentry p_c
) /*@modifies p_c@
*/;
72 static
/*@only@
*/ ctentry
73 ctentry_make
(ctkind p_ctk
, /*@keep@
*/ ctbase p_c
, ctype p_base
,
74 ctype p_ptr
, ctype p_array
, /*@keep@
*/ cstring p_unparse
);
75 static
/*@only@
*/ ctentry ctentry_makeNew
(ctkind p_ctk
, /*@only@
*/ ctbase p_c
);
76 static
/*@only@
*/ cstring ctentry_unparse
(ctentry p_c
) /*@
*/ ;
78 static void cttable_grow
(void
);
79 static ctype cttable_addDerived
(ctkind p_ctk
, /*@keep@
*/ ctbase p_cnew
, ctype p_base
);
80 static ctype cttable_addFull
(/*@keep@
*/ ctentry p_cnew
);
81 static bool ctentry_isInteresting
(ctentry p_c
) /*@
*/;
82 static
/*@notnull@
*/ /*@only@
*/ ctbase ctbase_makeFixedArray
(ctype p_b
, size_t p_size
) /*@
*/ ;
83 static bool ctbase_isAnytype
(/*@notnull@
*/ ctbase p_b
) /*@
*/ ;
86 ** These are file-static macros
(used in ctype.c
). No way to
87 ** declare them as static in C.
90 /*@
-allmacros@
*/ /*@
-macrospec@
*/ /*@
-namechecks@
*/
91 # define ctentry_getBase
(c
) ((c
)->base
)
92 # define ctentry_getKind
(c
) ((c
)->kind
)
93 # define ctentry_getArray
(c
) ((c
)->array
)
94 # define ctentry_getPtr
(c
) ((c
)->ptr
)
95 # define ctentry_isArray
(c
) ((c
)->kind
== CTK_ARRAY
)
96 # define ctentry_isComplex
(c
) ((c
)->kind
== CTK_COMPLEX
)
97 # define ctentry_isPlain
(c
) ((c
)->kind
== CTK_PLAIN
)
98 # define ctentry_isPointer
(c
) ((c
)->kind
== CTK_PTR
)
99 # define ctentry_setArray
(c
,b
) ((c
)->array
= (b
))
100 # define ctentry_setPtr
(c
,b
) ((c
)->ptr
= (b
))
102 # define ctbase_fixUser
(c
) (c
= ctbase_realType
(c
))
103 /*@
=allmacros@
*/ /*@
=macrospec@
*/ /*@
=namechecks@
*/
105 static ctype cttable_addComplex
(/*@notnull@
*/ /*@only@
*/ ctbase p_cnew
);
106 static
/*@observer@
*/ ctbase ctype_getCtbase
(ctype p_c
) /*@
*/ ;
107 static ctype ctype_makeConjAux
(ctype p_c1
, ctype p_c2
, bool p_isExplicit
) /*@
*/ ;
108 static
/*@notnull@
*/ /*@observer@
*/ ctbase ctype_getCtbaseSafe
(ctype p_c
) /*@
*/ ;
109 static
/*@observer@
*/ ctentry ctype_getCtentry
(ctype p_c
) /*@
*/ ;
110 static
/*@observer@
*/ /*@notnull@
*/ ctbase
111 ctbase_realType
(/*@notnull@
*/ ctbase p_c
) /*@
*/ ;
112 static bool ctbase_isPointer
(/*@notnull@
*/ /*@dependent@
*/ ctbase p_c
) /*@
*/ ;
113 static bool ctbase_isEitherArray
(/*@notnull@
*/ /*@dependent@
*/ ctbase p_c
) /*@
*/ ;
114 static
/*@observer@
*/ enumNameList ctbase_elist
(ctbase p_c
) /*@
*/ ;
115 static
/*@only@
*/ cstring ctbase_unparse
(ctbase p_c
) /*@
*/ ;
116 static
/*@only@
*/ cstring ctbase_unparseDeep
(ctbase p_c
) /*@
*/ ;
117 static void ctbase_free
(/*@only@
*/ ctbase p_c
);
118 static
/*@notnull@
*/ /*@only@
*/ ctbase ctbase_createPrim
(cprim p_p
) /*@
*/ ;
119 static
/*@notnull@
*/ /*@only@
*/ ctbase ctbase_createBool
(void
) /*@
*/ ;
120 static
/*@notnull@
*/ /*@observer@
*/ ctbase ctbase_getBool
(void
) /*@
*/ ;
121 static
/*@notnull@
*/ /*@only@
*/ ctbase ctbase_createUser
(typeId p_u
) /*@
*/ ;
123 static
/*@notnull@
*/ /*@only@
*/ ctbase
124 ctbase_createStruct
(/*@only@
*/ cstring p_n
, /*@only@
*/ uentryList p_f
);
126 static
/*@notnull@
*/ /*@only@
*/ ctbase
127 ctbase_createUnion
(/*@keep@
*/ cstring p_n
, /*@only@
*/ uentryList p_f
);
128 static
/*@notnull@
*/ /*@only@
*/ ctbase ctbase_createEnum
(/*@keep@
*/ cstring p_etag
, /*@keep@
*/ enumNameList p_emembers
);
129 static
/*@notnull@
*/ /*@only@
*/ ctbase ctbase_createUnknown
(void
);
130 static bool ctbase_match
(ctbase p_c1
, ctbase p_c2
) /*@modifies nothing@
*/;
131 static bool ctbase_matchDef
(ctbase p_c1
, ctbase p_c2
) /*@modifies nothing@
*/;
132 static bool ctbase_genMatch
(ctbase p_c1
, ctbase p_c2
, bool p_force
, bool p_arg
, bool p_def
, bool p_deep
);
133 static bool ctbase_isAbstract
(/*@notnull@
*/ ctbase p_c
) /*@
*/ ;
134 static
/*@notnull@
*/ /*@only@
*/ ctbase ctbase_makePointer
(ctype p_b
) /*@
*/ ;
135 static
/*@notnull@
*/ /*@only@
*/ ctbase ctbase_makeArray
(ctype p_b
) /*@
*/ ;
136 static
/*@notnull@
*/ ctype
137 ctbase_makeFunction
(ctype p_b
, /*@only@
*/ uentryList p_p
) /*@
*/ ;
138 static
/*@notnull@
*/ /*@observer@
*/ ctbase
139 ctbase_realFunction
(/*@notnull@
*/ /*@dependent@
*/ ctbase p_c
) /*@
*/ ;
140 static ctype ctbase_baseArrayPtr
(/*@notnull@
*/ ctbase p_c
) /*@
*/ ;
141 static ctype ctbase_baseFunction
(/*@notnull@
*/ ctbase p_c
) /*@
*/ ;
142 static
/*@observer@
*/ uentryList ctbase_argsFunction
(/*@notnull@
*/ ctbase p_c
) /*@
*/ ;
143 static
/*@observer@
*/ uentryList ctbase_getuentryList
(/*@notnull@
*/ ctbase p_c
) /*@
*/ ;
144 static ctype ctbase_newBase
(ctype p_c
, ctype p_p
) /*@
*/ ;
145 static ctype ctbase_newBaseExpFcn
(ctype p_c
, ctype p_p
) /*@
*/ ;
146 static bool ctbase_isFixedArray
(/*@notnull@
*/ ctbase p_c
) /*@
*/ ;
149 extern int cttable_lastIndex
(void
);
150 # define cttable_lastIndex
() (cttab.size
- 1)
156 /*@only@
*/ uentryList params
;
175 enumNameList members
;
186 cprim prim
; /* primitive
*/
187 typeId tid
; /* abstract
, user
*/
188 ctype base
; /* ptr
, array
*/
189 cfcn fcn
; /* function
*/
190 tsu su
; /* struct union
*/
191 tenum cenum
; /* enum
*/
192 tconj conj
; /* conj
*/
193 tfixed farray
; /* fixed array
*/
202 static
/*@falsenull@
*/ bool ctbase_isUA
(ctbase p_c
) /*@
*/ ;
203 static bool ctbase_isKind
(/*@notnull@
*/ ctbase p_c
, ctuid p_kind
) /*@
*/ ;
204 static
/*@falsenull@
*/ bool ctbase_isFunction
(ctbase p_c
) /*@
*/ ;
206 /*@constant null ctbase ctbase_undefined
; @
*/
207 # define ctbase_undefined
((ctbase
)0)
209 static
/*@owned@
*/ ctbase ctbase_bool
= ctbase_undefined
;
210 static
/*@owned@
*/ ctbase ctbase_unknown
= ctbase_undefined
;
212 static
/*@falsenull@
*/ bool ctbase_isDefined
(ctbase c
) /*@
*/
214 return
((c
) != ctbase_undefined
);
217 static
/*@truenull@
*/ bool ctbase_isUndefined
(ctbase c
)
219 return
((c
) == ctbase_undefined
);
222 static ctkind ctype_getCtKind
(ctype c
)
224 ctentry ce
= ctype_getCtentry
(c
);
226 return ctentry_getKind
(ce
);
229 static bool ctbase_isUser
(ctbase c
)
231 if
(ctbase_isDefined
(c
))
233 return
(ctbase_isKind
(c
, CT_USER
));
241 static bool ctbase_isEnum
(ctbase c
)
243 if
(ctbase_isDefined
(c
))
245 return
(ctbase_isKind
(c
, CT_ENUM
));
253 static bool ctbase_isExpFcn
(ctbase c
)
255 if
(ctbase_isDefined
(c
))
257 return
(c-
>type
== CT_EXPFCN
);
265 static
/*@falsenull@
*/ bool ctbase_isConj
(ctbase c
)
267 if
(ctbase_isDefined
(c
))
269 return
(c-
>type
== CT_CONJ
);
277 static bool ctuid_isAP
(ctuid c
) /*@
*/
279 return
(c
== CT_ARRAY || c
== CT_PTR
);
282 static typeId ctbase_typeId
(ctbase p_c
);
283 static
/*@only@
*/ cstring ctbase_dump
(ctbase p_c
);
284 static
/*@only@
*/ ctbase ctbase_undump
(char
**p_c
) /*@requires maxRead
(*p_c
) >= 2 @
*/;
285 static int ctbase_compare
(ctbase p_c1
, ctbase p_c2
, bool p_strict
);
286 static bool ctbase_matchArg
(ctbase p_c1
, ctbase p_c2
);
287 static
/*@notnull@
*/ /*@only@
*/ ctbase
288 ctbase_makeConj
(ctype p_c1
, ctype p_c2
, bool p_isExplicit
) /*@
*/ ;
289 static ctype ctbase_getConjA
(/*@notnull@
*/ ctbase p_c
) /*@
*/ ;
290 static ctype ctbase_getConjB
(/*@notnull@
*/ ctbase p_c
) /*@
*/ ;
291 static bool ctbase_isExplicitConj
(/*@notnull@
*/ ctbase p_c
) /*@
*/ ;
292 static bool ctbase_forceMatch
(ctbase p_c1
, ctbase p_c2
) /*@modifies p_c1
, p_c2@
*/ ;
293 static
/*@notnull@
*/ /*@only@
*/ ctbase ctbase_expectFunction
(ctype p_c
);
294 static bool ctbase_isVoidPointer
(/*@notnull@
*/ /*@dependent@
*/ ctbase p_c
) /*@
*/ ;
295 static bool ctbase_isUnion
(/*@notnull@
*/ /*@temp@
*/ ctbase p_c
) /*@
*/ ;
296 static bool ctbase_isStruct
(/*@notnull@
*/ /*@temp@
*/ ctbase p_c
) /*@
*/ ;
297 static
/*@observer@
*/ cstring ctbase_enumTag
(/*@notnull@
*/ ctbase p_ct
) /*@
*/ ;
299 static
/*@out@
*/ /*@notnull@
*/ /*@only@
*/ ctbase ctbase_new
(void
) /*@
*/ ;
300 static int nctbases
= 0;
302 static
/*@notnull@
*/ /*@only@
*/
303 ctbase ctbase_makeLiveFunction
(ctype p_b
, /*@only@
*/ uentryList p_p
);
306 static bool ctbase_isUnnamedSU
(ctbase c
)
308 return
(ctbase_isDefined
(c
)
309 && (ctbase_isStruct (c) || ctbase_isUnion (c))
310 && isFakeTag (c->contents.su->name));
312 # endif
/* DEADCODE
*/
314 static
/*@observer@
*/ ctbase ctbase_realType
(ctbase c
)
318 typeId uid
= ctbase_typeId
(c
);
320 if
(usymtab_isBoolType
(uid
))
322 return ctbase_getBool
();
326 ctbase ret
= ctype_getCtbase
327 (uentry_getRealType
(usymtab_getTypeEntry
(ctbase_typeId
(c
))));
329 llassert
(ret
!= ctbase_undefined
);
340 ctbase_isVoidPointer
(/*@dependent@
*/ /*@notnull@
*/ ctbase c
)
342 ctbase r
= ctbase_realType
(c
);
344 return
(ctbase_isKind
(r
, CT_PTR
) &&
345 ctype_isVoid
(r-
>contents.base
));
349 ctbase_isPointer
(/*@notnull@
*/ /*@dependent@
*/ ctbase c
)
351 ctbase r
= ctbase_realType
(c
);
353 return
(ctbase_isKind
(r
, CT_PTR
));
357 ctbase_isEitherArray
(/*@notnull@
*/ ctbase c
)
359 ctbase r
= ctbase_realType
(c
);
361 return
(ctbase_isKind
(r
, CT_ARRAY
)
362 || ctbase_isKind
(r
, CT_FIXEDARRAY
));
366 ctbase_isFixedArray
(/*@notnull@
*/ ctbase c
)
368 ctbase r
= ctbase_realType
(c
);
370 return
(ctbase_isKind
(r
, CT_FIXEDARRAY
));
374 ctbase_isStruct
(/*@notnull@
*/ ctbase c
)
376 ctbase r
= ctbase_realType
(c
);
378 return
(ctbase_isKind
(r
, CT_STRUCT
));
382 ctbase_isUnion
(/*@notnull@
*/ ctbase c
)
384 ctbase r
= ctbase_realType
(c
);
386 return
(ctbase_isKind
(r
, CT_UNION
));
390 ** clean this up
-> typeTable should store ctype
395 ctbase_typeBaseUid
(ctbase c
)
399 if
(ctbase_isDefined
(c
))
405 return ctbase_typeBaseUid
(ctype_getCtbase
(c-
>contents.base
));
407 else if
(ct
== CT_USER || ct
== CT_ABST || ct
== CT_NUMABST
)
409 return c-
>contents.tid
;
411 else if
(ct
== CT_FIXEDARRAY
)
413 return ctbase_typeBaseUid
(ctype_getCtbase
(c-
>contents.farray-
>base
));
417 llcontbuglit
("ctbase_typeBaseUid: bad call");
418 return typeId_invalid
;
421 return typeId_invalid
;
425 ctbase_isBaseUA
(ctbase c
)
429 if
(ctbase_isDefined
(c
))
435 return ctbase_isBaseUA
(ctype_getCtbase
(c-
>contents.base
));
437 else if
(ct
== CT_FIXEDARRAY
)
439 return ctbase_isBaseUA
(ctype_getCtbase
(c-
>contents.farray-
>base
));
442 return
(ct
== CT_USER || ct
== CT_ABST || ct
== CT_NUMABST
);
449 ctbase_typeId
(ctbase c
)
453 return c-
>contents.tid
;
457 if
(ctbase_isConj
(c
))
459 if
(ctype_isUA
(ctbase_getConjA
(c
))) {
460 return ctbase_typeId
(ctype_getCtbase
(ctbase_getConjA
(c
)));
461 } else if
(ctype_isUA
(ctbase_getConjB
(c
))) {
462 return ctbase_typeId
(ctype_getCtbase
(ctbase_getConjB
(c
)));
464 llcontbug
(message
("ctbase_typeId: bad call: %q", ctbase_unparse
(c
)));
465 return typeId_invalid
;
470 llcontbug
(message
("ctbase_typeId: bad call: %q", ctbase_unparse
(c
)));
471 return typeId_invalid
;
476 static
/*@only@
*/ cstring
477 ctbase_unparse
(ctbase c
)
479 if
(ctbase_isUndefined
(c
)) {
480 return cstring_makeLiteral
("<<undef>>");
486 return cstring_makeLiteral
("?");
488 return cstring_copy
(context_printBoolName
());
490 return
(cprim_unparse
(c-
>contents.prim
));
494 return
(usymtab_getTypeEntryName
(c-
>contents.tid
));
496 return
(message
("<expf: %t>", c-
>contents.base
));
498 /* no spaces for multiple pointers
*/
500 if
(ctype_isPointer
(c-
>contents.base
))
502 return
(cstring_appendChar
(cstring_copy
(ctype_unparse
(c-
>contents.base
)), '
*'
));
506 return
(message
("%t *", c-
>contents.base
));
510 ** C prints out array declarations backwards
, if
511 ** base is an array need to print out in reverse order.
514 if
(ctype_isArray
(c-
>contents.farray-
>base
))
516 ctype base
= c-
>contents.farray-
>base
;
517 cstring res
= message
("[%d]", (int
) c-
>contents.farray-
>size
);
519 while
(ctype_isArray
(base
))
521 if
(ctype_isFixedArray
(base
))
523 res
= message
("%q[%d]",
524 res
, (int
) ctype_getArraySize
(base
));
528 res
= message
("%q[]", res
);
531 base
= ctype_baseArrayPtr
(base
);
534 return
(message
("%t %q", base
, res
));
538 return
(message
("%t [%d]",
539 c-
>contents.farray-
>base
,
540 (int
) c-
>contents.farray-
>size
));
543 if
(ctype_isArray
(c-
>contents.base
))
545 ctype base
= c-
>contents.base
;
546 cstring res
= cstring_makeLiteral
("[]");
548 while
(ctype_isArray
(base
))
550 if
(ctype_isFixedArray
(base
))
552 res
= message
("%q[%d]",
553 res
, (int
) ctype_getArraySize
(base
));
557 res
= message
("%q[]", res
);
560 base
= ctype_baseArrayPtr
(base
);
563 return
(message
("%t %q", base
, res
));
568 return
(message
("%t []", c-
>contents.base
));
571 return
(message
("[function (%q) returns %t]",
572 uentryList_unparseParams
(c-
>contents.fcn-
>params
),
573 c-
>contents.fcn-
>rval
));
575 if
(cstring_isDefined
(c-
>contents.su-
>name
) &&
576 !cstring_isEmpty
(c-
>contents.su-
>name
) &&
577 !isFakeTag
(c-
>contents.su-
>name
))
579 return
(message
("struct %s", c-
>contents.su-
>name
));
583 return
(message
("struct { %q }",
584 uentryList_unparseAbbrev
(c-
>contents.su-
>fields
)));
587 if
(cstring_isDefined
(c-
>contents.su-
>name
) &&
588 !cstring_isEmpty
(c-
>contents.su-
>name
) &&
589 !isFakeTag
(c-
>contents.su-
>name
))
591 return
(message
("union %s", c-
>contents.su-
>name
));
595 return
(message
("union { %q }",
596 uentryList_unparseAbbrev
(c-
>contents.su-
>fields
)));
599 if
(isFakeTag
(c-
>contents.cenum-
>tag
))
601 return
(message
("enum { %q }",
602 enumNameList_unparseBrief
(c-
>contents.cenum-
>members
)));
606 return
(message
("enum %s { %q }",
607 c-
>contents.cenum-
>tag
,
608 enumNameList_unparseBrief
(c-
>contents.cenum-
>members
)));
611 if
(ctbase_isAnytype
(c
))
613 return
(cstring_makeLiteral
("<any>"));
615 else if
(c-
>contents.conj-
>isExplicit || context_getFlag
(FLG_SHOWALLCONJS
))
617 if
(!ctype_isSimple
(c-
>contents.conj-
>a
) ||
618 !ctype_isSimple
(c-
>contents.conj-
>b
))
620 return
(message
("<%t> | <%t>", c-
>contents.conj-
>a
, c-
>contents.conj-
>b
));
624 return
(message
("%t | %t", c-
>contents.conj-
>a
, c-
>contents.conj-
>b
));
629 return
(cstring_copy
(ctype_unparse
(c-
>contents.conj-
>a
)));
636 static
/*@only@
*/ cstring
637 ctbase_unparseDeep
(ctbase c
)
639 if
(ctbase_isUndefined
(c
))
641 return cstring_makeLiteral
("<<undef>>");
647 return cstring_makeLiteral
("?");
649 return cstring_copy
(context_printBoolName
());
651 return
(cprim_unparse
(c-
>contents.prim
));
653 if
(cstring_isNonEmpty
(c-
>contents.cenum-
>tag
))
655 return
(message
("enum %s { %q }",
656 c-
>contents.cenum-
>tag
,
657 enumNameList_unparse
(c-
>contents.cenum-
>members
)));
661 return
(message
("enum { %q }",
662 enumNameList_unparse
(c-
>contents.cenum-
>members
)));
667 return
(usymtab_getTypeEntryName
(c-
>contents.tid
));
669 return
(message
("<expf: %t>", c-
>contents.base
));
671 return
(message
("%t *", c-
>contents.base
));
673 return
(message
("%t [%d]", c-
>contents.farray-
>base
,
674 (int
) c-
>contents.farray-
>size
));
676 return
(message
("%t []", c-
>contents.base
));
678 return
(message
("[function (%q) returns %t]",
679 uentryList_unparse
(c-
>contents.fcn-
>params
),
680 c-
>contents.fcn-
>rval
));
682 return
(message
("struct %s { ... } ", c-
>contents.su-
>name
));
684 return
(message
("union %s { ... }", c-
>contents.su-
>name
));
686 if
(ctbase_isAnytype
(c
))
688 return
(cstring_makeLiteral
("<any>"));
692 return
(message
("%t", c-
>contents.conj-
>a
));
700 static
/*@only@
*/ cstring
701 ctbase_unparseNotypes
(ctbase c
)
703 llassertfatal
(ctbase_isDefined
(c
));
708 return cstring_makeLiteral
("?");
710 return cstring_copy
(context_printBoolName
());
712 return
(cprim_unparse
(c-
>contents.prim
));
714 if
(typeId_isInvalid
(c-
>contents.tid
))
716 return cstring_makeLiteral
("enum");
720 return
(message
("T#%d", c-
>contents.tid
));
723 return
(message
("uT#%d", c-
>contents.tid
));
725 return
(message
("aT#%d", c-
>contents.tid
));
727 return
(message
("nT#%d", c-
>contents.tid
));
729 return
(message
("<expf: %q >", ctbase_unparseNotypes
(ctype_getCtbase
(c-
>contents.base
))));
731 return
(message
("%q *", ctbase_unparseNotypes
(ctype_getCtbase
(c-
>contents.base
))));
733 return
(message
("%q []", ctbase_unparseNotypes
(ctype_getCtbase
(c-
>contents.base
))));
735 return
(message
("[function (%d) returns %q]", uentryList_size
(c-
>contents.fcn-
>params
),
736 ctbase_unparseNotypes
(ctype_getCtbase
(c-
>contents.fcn-
>rval
))));
738 return
(message
("struct %s", c-
>contents.su-
>name
));
740 return
(message
("union %s", c-
>contents.su-
>name
));
742 return
(message
("[enumlist]"));
744 if
(ctbase_isAnytype
(c
))
746 return
(cstring_makeLiteral
("<any>"));
750 return
(message
("%q/%q",
751 ctbase_unparseNotypes
(ctype_getCtbase
(c-
>contents.conj-
>a
)),
752 ctbase_unparseNotypes
(ctype_getCtbase
(c-
>contents.conj-
>b
))));
760 static
/*@only@
*/ cstring
761 ctbase_unparseDeclaration
(ctbase c
, /*@only@
*/ cstring name
) /*@
*/
763 if
(ctbase_isUndefined
(c
))
771 return
(message
("? %q", name
));
773 return
(message
("%s %q", context_printBoolName
(), name
));
775 return
(message
("%q %q", cprim_unparse
(c-
>contents.prim
), name
));
779 return
(message
("%q %q", usymtab_getTypeEntryName
(c-
>contents.tid
), name
));
781 llcontbuglit
("ctbase_unparseDeclaration: expfcn");
784 if
(ctype_isFunction
(c-
>contents.base
))
786 return ctbase_unparseDeclaration
(ctype_getCtbase
(c-
>contents.base
), name
);
790 cstring s
= cstring_prependChar
('
*'
, name
);
791 cstring ret
= ctbase_unparseDeclaration
(ctype_getCtbase
(c-
>contents.base
), s
);
796 return
(message
("%q[%d]",
797 ctbase_unparseDeclaration
(ctype_getCtbase
(c-
>contents.farray-
>base
), name
),
798 (int
) c-
>contents.farray-
>size
));
800 return
(message
("%q[]",
801 ctbase_unparseDeclaration
(ctype_getCtbase
(c-
>contents.base
), name
)));
804 cstring s
= message
("%q(%q)", name
,
805 uentryList_unparseParams
(c-
>contents.fcn-
>params
));
807 return
(ctbase_unparseDeclaration
808 (ctype_getCtbase
(c-
>contents.fcn-
>rval
), s
));
811 if
(cstring_isDefined
(c-
>contents.su-
>name
) &&
812 !cstring_isEmpty
(c-
>contents.su-
>name
) &&
813 !isFakeTag
(c-
>contents.su-
>name
))
815 return
(message
("struct %s %q", c-
>contents.su-
>name
, name
));
819 return
(message
("struct { %q } %q",
820 uentryList_unparseAbbrev
(c-
>contents.su-
>fields
),
824 if
(cstring_isDefined
(c-
>contents.su-
>name
) &&
825 !cstring_isEmpty
(c-
>contents.su-
>name
) &&
826 !isFakeTag
(c-
>contents.su-
>name
))
828 return
(message
("union %s %q", c-
>contents.su-
>name
, name
));
832 return
(message
("union { %q } %q",
833 uentryList_unparseAbbrev
(c-
>contents.su-
>fields
),
837 if
(isFakeTag
(c-
>contents.cenum-
>tag
))
839 return
(message
("enum { %q } %q",
840 enumNameList_unparseBrief
(c-
>contents.cenum-
>members
),
845 return
(message
("enum %s { %q } %q",
846 c-
>contents.cenum-
>tag
,
847 enumNameList_unparseBrief
(c-
>contents.cenum-
>members
),
851 if
(ctbase_isAnytype
(c
))
853 return
(message
("<any> %q", name
));
855 else if
(c-
>contents.conj-
>isExplicit || context_getFlag
(FLG_SHOWALLCONJS
))
857 if
(!ctype_isSimple
(c-
>contents.conj-
>a
) ||
858 !ctype_isSimple
(c-
>contents.conj-
>b
))
860 cstring name1
= cstring_copy
(name
);
865 ctbase_unparseDeclaration
866 (ctype_getCtbase
(c-
>contents.conj-
>a
), name1
),
867 ctbase_unparseDeclaration
868 (ctype_getCtbase
(c-
>contents.conj-
>b
), name
)));
872 cstring s1
= ctbase_unparseDeclaration
(ctype_getCtbase
(c-
>contents.conj-
>a
),
873 cstring_copy
(name
));
875 (message
("%q | %q", s1
,
876 ctbase_unparseDeclaration
(ctype_getCtbase
(c-
>contents.conj-
>b
),
883 return
(cstring_copy
(ctype_unparse
(c-
>contents.conj-
>a
)));
890 static ctbase ctbase_undump
(d_char
*c
) /*@requires maxRead
(*c
) >= 2 @
*/
900 return
(ctbase_undefined
);
902 return
(ctbase_createUnknown
());
904 return
(ctbase_createBool
());
906 res
= ctbase_createPrim
(cprim_fromInt
(reader_getInt
(c
)));
907 reader_checkChar
(c
, '|'
);
910 res
= ctbase_createUser
(typeId_fromInt
(reader_getInt
(c
)));
911 reader_checkChar
(c
, '|'
);
914 res
= ctbase_createAbstract
(typeId_fromInt
(reader_getInt
(c
)));
915 reader_checkChar
(c
, '|'
);
918 res
= ctbase_createNumAbstract
(typeId_fromInt
(reader_getInt
(c
)));
919 reader_checkChar
(c
, '|'
);
922 res
= ctbase_makePointer
(ctype_undump
(c
));
923 reader_checkChar
(c
, '|'
);
926 res
= ctbase_makeArray
(ctype_undump
(c
));
927 reader_checkChar
(c
, '|'
);
931 ctype ct
= ctype_undump
(c
);
934 reader_checkChar
(c
, '
/'
);
935 size
= size_fromInt
(reader_getInt
(c
));
936 reader_checkChar
(c
, '|'
);
937 return
(ctbase_makeFixedArray
(ct
, size
));
942 char
*lp
= strchr
(*c
, '
('
);
944 llassertfatal
(lp
!= NULL);
947 ct
= ctype_undump
(c
);
950 return
(ctbase_makeLiveFunction
(ct
, uentryList_undump
(c
)));
957 char
*lc
= strchr
(*c
, '
{'
);
959 llassertfatal
(lc
!= NULL);
962 sname
= mstring_copy
(*c
);
970 i
= (unsigned
) atoi
(sname
+ 1);
975 fields
= uentryList_undumpFields
(c
, g_currentloc
);
977 ctb
= ctbase_createStruct
(cstring_fromCharsO
(sname
), fields
);
983 char
*lc
= strchr
(*c
, '
{'
);
985 llassertfatal
(lc
!= NULL);
988 sname
= mstring_copy
(*c
);
989 llassertfatal
(sname
!= NULL);
997 i
= (unsigned
) atoi
(sname
+ 1);
1001 return
(ctbase_createUnion
(cstring_fromCharsO
(sname
),
1002 uentryList_undumpFields
(c
, g_currentloc
)));
1008 char
*lc
= strchr
(*c
, '
{'
);
1010 llassertfatal
(lc
!= NULL);
1013 sname
= mstring_copy
(*c
);
1020 i
= (unsigned
) atoi
(sname
+ 1);
1024 ret
= ctbase_createEnum
(cstring_fromCharsO
(sname
),
1025 enumNameList_undump
(c
));
1033 isExplicit
= bool_fromInt
(reader_getInt
(c
));
1034 reader_checkChar
(c
, '.'
);
1035 c1
= ctype_undump
(c
);
1036 reader_checkChar
(c
, '
/'
);
1037 c2
= ctype_undump
(c
);
1038 reader_checkChar
(c
, '|'
);
1040 return
(ctbase_makeConj
(c1
, c2
, isExplicit
));
1045 llerror
(FLG_SYNTAX
,
1046 message
("Bad Library line (type): %s", cstring_fromChars
(*c
)));
1048 /*drl bee
: pbr
*/ while
(**c
!= '\
0'
)
1053 return ctbase_createUnknown
();
1057 /* first letter of c encodes type
: */
1073 static
/*@only@
*/ cstring
1074 ctbase_dump
(ctbase c
)
1076 if
(!ctbase_isDefined
(c
))
1078 return cstring_makeLiteral
("?");
1084 return cstring_makeLiteral
("u");
1086 return cstring_makeLiteral
("b");
1088 return
(message
("p%d|", c-
>contents.prim
));
1090 return
(message
("s%d|", usymtab_convertTypeId
(c-
>contents.tid
)));
1092 return
(message
("a%d|", usymtab_convertTypeId
(c-
>contents.tid
)));
1094 return
(message
("n%d|", usymtab_convertTypeId
(c-
>contents.tid
)));
1096 return
(message
("t%q|", ctype_dump
(c-
>contents.base
)));
1098 return
(message
("y%q|", ctype_dump
(c-
>contents.base
)));
1100 return
(message
("F%q/%d|",
1101 ctype_dump
(c-
>contents.farray-
>base
),
1102 (int
) c-
>contents.farray-
>size
));
1104 DPRINTF
(("Dump function: %s", ctbase_unparse
(c
)));
1105 return
(message
("f%q (%q)", ctype_dump
(c-
>contents.fcn-
>rval
),
1106 uentryList_dumpParams
(c-
>contents.fcn-
>params
)));
1108 return
(message
("S%s{%q}", c-
>contents.su-
>name
,
1109 uentryList_dumpFields
(c-
>contents.su-
>fields
)));
1111 return
(message
("U%s{%q}", c-
>contents.su-
>name
,
1112 uentryList_dumpFields
(c-
>contents.su-
>fields
)));
1117 if
(cstring_isNonEmpty
(c-
>contents.cenum-
>tag
))
1119 s
= message
("e%s{%q}",
1120 c-
>contents.cenum-
>tag
,
1121 enumNameList_dump
(c-
>contents.cenum-
>members
));
1125 s
= message
("e{%q}",
1126 enumNameList_dump
(c-
>contents.cenum-
>members
));
1131 return
(message
("C%d.%q/%q|",
1132 bool_toInt
(c-
>contents.conj-
>isExplicit
),
1133 ctype_dump
(c-
>contents.conj-
>a
),
1134 ctype_dump
(c-
>contents.conj-
>b
)));
1136 /* should clean them up
! */
1137 return
(cstring_makeLiteral
("?"));
1139 llcontbug
(message
("Cannot dump: %q", ctbase_unparse
(c
)));
1140 return
(message
("u"));
1148 static
/*@only@
*/ ctbase
1149 ctbase_copy
(/*@notnull@
*/ ctbase c
)
1154 return
(ctbase_createUnknown
());
1156 return
(ctbase_createBool
());
1158 return
(ctbase_createEnum
(cstring_copy
(c-
>contents.cenum-
>tag
),
1159 enumNameList_copy
(c-
>contents.cenum-
>members
)));
1161 return
(ctbase_createPrim
(c-
>contents.prim
));
1163 return
(ctbase_createUser
(c-
>contents.tid
));
1165 return
(ctbase_createAbstract
(c-
>contents.tid
));
1167 return
(ctbase_createNumAbstract
(c-
>contents.tid
));
1169 return
(ctbase_expectFunction
(c-
>contents.base
));
1171 return
(ctbase_makePointer
(c-
>contents.base
));
1173 return
(ctbase_makeArray
(c-
>contents.base
));
1175 return
(ctbase_makeLiveFunction
(c-
>contents.fcn-
>rval
,
1176 uentryList_copy
(c-
>contents.fcn-
>params
)));
1178 return
(ctbase_createStruct
(cstring_copy
(c-
>contents.su-
>name
),
1179 uentryList_copy
(c-
>contents.su-
>fields
)));
1181 return
(ctbase_createUnion
(cstring_copy
(c-
>contents.su-
>name
),
1182 uentryList_copy
(c-
>contents.su-
>fields
)));
1184 /*@i@
*/ return
(c
); /* not a real copy for conj's
*/
1186 llbug
(message
("ctbase_copy: %q", ctbase_unparse
(c
)));
1194 ctbase_elist
(ctbase c
)
1196 llassertfatal
(ctbase_isDefined
(c
));
1197 llassert
(c-
>type
== CT_ENUM
);
1199 return
(c-
>contents.cenum-
>members
);
1203 ctbase_free
(/*@only@
*/ ctbase c
)
1205 if
(c
== ctbase_bool || c
== ctbase_unknown
)
1207 /*@
-mustfree@
*/ return
; /*@
=mustfree@
*/
1213 if
(ctbase_isDefined
(c
))
1240 uentryList_free
(c-
>contents.fcn-
>params
);
1245 cstring_free
(c-
>contents.su-
>name
);
1246 uentryList_free
(c-
>contents.su-
>fields
);
1250 /* Don't free conj's
, */
1260 ** c should be
* <unknown
>
1263 static
/*@only@
*/ ctbase
1264 ctbase_expectFunction
(ctype c
)
1266 ctbase f
= ctbase_new
();
1268 f-
>type
= CT_EXPFCN
;
1269 f-
>contents.base
= c
;
1275 ctbase_getExpectFunction
(/*@notnull@
*/ ctbase ct
)
1277 llassert
(ct-
>type
== CT_EXPFCN
);
1278 return ct-
>contents.base
;
1282 ctbase_genMatch
(ctbase c1
, ctbase c2
, bool force
, bool arg
, bool def
, bool deep
)
1286 /* undefined types never match
*/
1288 if
(ctbase_isUndefined
(c1
) || ctbase_isUndefined
(c2
))
1291 /* abstract types match user types of same name
*/
1293 c1
= ctbase_realType
(c1
);
1294 c2
= ctbase_realType
(c2
);
1296 DPRINTF
(("Matching: %s / %s", ctbase_unparse
(c1
),
1297 ctbase_unparse
(c2
)));
1302 if
(c1tid
== CT_CONJ
)
1304 return
(ctbase_genMatch
(ctype_getCtbase
(c1-
>contents.conj-
>a
), c2
,
1305 force
, arg
, def
, deep
)
1306 || ctbase_genMatch
(ctype_getCtbase
(c1-
>contents.conj-
>b
), c2
,
1307 force
, arg
, def
, deep
));
1310 if
(c2tid
== CT_CONJ
)
1312 return
(ctbase_genMatch
(c1
, ctype_getCtbase
(c2-
>contents.conj-
>a
),
1313 force
, arg
, def
, deep
)
1314 || ctbase_genMatch
(c1
, ctype_getCtbase
(c2-
>contents.conj-
>b
),
1315 force
, arg
, def
, deep
));
1319 ** if the types don't match
, there are some special cases...
1324 /* unknowns match anything
*/
1326 if
(c1tid
== CT_UNKNOWN || c2tid
== CT_UNKNOWN
)
1331 if
(c1tid
== CT_FIXEDARRAY
1332 && (c2tid == CT_ARRAY || (!def && c2tid == CT_PTR)))
1334 if
(ctype_isVoid
(c2-
>contents.base
))
1336 return
(context_getFlag
(FLG_ABSTVOIDP
) ||
1337 (!(ctype_isRealAbstract
(c1-
>contents.farray-
>base
)) &&
1338 !(ctype_isRealAbstract
(c2-
>contents.base
))));
1341 return
(ctbase_genMatch
(ctype_getCtbase
(c1-
>contents.farray-
>base
),
1342 ctype_getCtbase
(c2-
>contents.base
),
1343 force
, arg
, def
, deep
));
1347 if
(c2tid
== CT_FIXEDARRAY
1348 && (c1tid == CT_ARRAY || (!def && c1tid == CT_PTR)))
1350 if
(ctype_isVoid
(c1-
>contents.base
))
1352 return
(context_getFlag
(FLG_ABSTVOIDP
) ||
1353 (!(ctype_isRealAbstract
(c2-
>contents.farray-
>base
)) &&
1354 !(ctype_isRealAbstract
(c1-
>contents.base
))));
1357 return
(ctbase_genMatch
(ctype_getCtbase
(c1-
>contents.base
),
1358 ctype_getCtbase
(c2-
>contents.farray-
>base
),
1359 force
, arg
, def
, deep
));
1362 /* evs
2000-07-25: Bool's may match user
/abstract types
*/
1364 if
((c1tid
== CT_BOOL
1365 && (c2tid == CT_PRIM && cprim_isInt (c2->contents.prim))) ||
1367 && (c1tid == CT_PRIM && cprim_isInt (c1->contents.prim))))
1369 return
(context_msgBoolInt
());
1372 if
((c1tid
== CT_BOOL
&& (ctuid_isAnyUserType (c2tid)))) {
1373 ctype t2c
= c2-
>contents.base
;
1374 return
(ctype_isBool
(t2c
));
1377 if
((c2tid
== CT_BOOL
&& (ctuid_isAnyUserType (c1tid)))) {
1378 ctype t1c
= c1-
>contents.base
;
1380 return
(ctype_isBool
(t1c
));
1383 if
((c1tid
== CT_ENUM
1384 && (c2tid == CT_PRIM && cprim_isInt (c2->contents.prim))) ||
1386 && (c1tid == CT_PRIM && cprim_isInt (c1->contents.prim))))
1388 return
(context_msgEnumInt
());
1392 ** arrays and pointers...yuk
!
1394 ** Considered equivalent except in definitions.
1395 ** (e.g.
, function parameters are equivalent
)
1401 if
(ctuid_isAP
(c1tid
) && ctuid_isAP (c2tid))
1408 ** Function pointers can be removed.
1410 ** [function ..
] is equivalent to
[function ..
] *
1413 if
(c1tid
== CT_PTR
&& c2tid == CT_FCN)
1415 if
(ctype_isFunction
(ctype_realType
(c1-
>contents.base
)))
1417 c1
= ctbase_realType
(ctype_getCtbaseSafe
(c1-
>contents.base
));
1422 if
(c2tid
== CT_PTR
&& c1tid == CT_FCN)
1424 if
(ctype_isFunction
(ctype_realType
(c2-
>contents.base
)))
1426 c2
= ctbase_realType
(ctype_getCtbaseSafe
(c2-
>contents.base
));
1432 ** we allow forward declarations to structures like
,
1434 ** typedef struct _t
*t
;
1437 ** struct _t
* to match t
1440 if
(context_getFlag
(FLG_FORWARDDECL
))
1442 if
(ctuid_isAnyUserType
(c1tid
))
1444 if
(ctuid_isAP
(c2tid
))
1446 ctype ts
= c2-
>contents.base
;
1448 if
(ctype_isUA
(ts
))
1450 typeId ttid
= ctype_typeId
(ts
);
1451 typeId ctid
= c1-
>contents.tid
;
1453 if
(usymtab_matchForwardStruct
(ctid
, ttid
))
1461 if
(ctuid_isAnyUserType
(c2tid
))
1463 if
(ctuid_isAP
(c1tid
))
1465 ctype ts
= c1-
>contents.base
;
1467 if
(ctype_isUA
(ts
))
1469 typeId ttid
= ctype_typeId
(ts
);
1470 typeId ctid
= c2-
>contents.tid
;
1472 if
(usymtab_matchForwardStruct
(ctid
, ttid
))
1491 return
(cprim_closeEnoughDeep
(c1-
>contents.prim
, c2-
>contents.prim
));
1493 return
(cprim_closeEnough
(c1-
>contents.prim
, c2-
>contents.prim
));
1500 return
(typeId_equal
(c1-
>contents.tid
, c2-
>contents.tid
));
1502 return
(cstring_equal
(c1-
>contents.cenum-
>tag
, c2-
>contents.cenum-
>tag
));
1504 if
(ctype_isVoid
(c1-
>contents.base
)
1505 ||
(ctype_isVoid
(c2-
>contents.base
)))
1507 if
(ctype_isFunction
(ctype_realType
(c1-
>contents.base
))
1508 || ctype_isFunction
(ctype_realType
(c2-
>contents.base
)))
1510 return
(!context_getFlag
(FLG_CASTFCNPTR
));
1514 return
(context_getFlag
(FLG_ABSTVOIDP
) ||
1515 (!(ctype_isRealAbstract
(c1-
>contents.base
)) &&
1516 !(ctype_isRealAbstract
(c2-
>contents.base
))));
1521 /* Only allow one implicit function pointer.
*/
1523 if
(!bool_equal
(ctype_isRealPointer
(c1-
>contents.base
),
1524 ctype_isRealPointer
(c2-
>contents.base
))
1525 && (ctype_isRealFunction (c1->contents.base)
1526 || ctype_isRealFunction
(c2-
>contents.base
)))
1531 return
(ctype_genMatch
(c1-
>contents.base
,
1532 c2-
>contents.base
, force
, arg
, def
, TRUE));
1535 if
(ctype_isVoid
(c1-
>contents.farray-
>base
)
1536 || ctype_isVoid
(c2-
>contents.farray-
>base
))
1538 return
(ctype_genMatch
(c1-
>contents.farray-
>base
,
1539 c2-
>contents.farray-
>base
,
1540 force
, arg
, def
, deep
));
1542 if
(ctype_isVoid
(c1-
>contents.base
) || ctype_isVoid
(c2-
>contents.base
))
1544 return
(ctype_genMatch
(c1-
>contents.base
, c2-
>contents.base
, force
, arg
, def
, TRUE));
1546 return
(ctype_genMatch
(c1-
>contents.fcn-
>rval
,
1547 c2-
>contents.fcn-
>rval
,
1548 force
, arg
, def
, TRUE)
1549 && uentryList_matchParams (c1->contents.fcn->params,
1550 c2-
>contents.fcn-
>params
,
1554 DPRINTF
(("Struct: %s / %s",
1555 c1-
>contents.su-
>name
,
1556 c2-
>contents.su-
>name
));
1558 if
(isFakeTag
(c1-
>contents.su-
>name
)
1559 && isFakeTag (c2->contents.su->name))
1561 /* Both fake tags
, check structure
*/
1562 if
(cstring_equal
(c1-
>contents.su-
>name
, c2-
>contents.su-
>name
))
1568 return uentryList_matchFields
(c1-
>contents.su-
>fields
,
1569 c2-
>contents.su-
>fields
);
1574 if
(!cstring_isEmpty
(c1-
>contents.su-
>name
))
1576 return
(cstring_equal
(c1-
>contents.su-
>name
, c2-
>contents.su-
>name
));
1580 if
(!cstring_isEmpty
(c2-
>contents.su-
>name
))
1585 llcontbuglit
("ctbase_genMatch: match fields");
1590 llcontbug
(message
("ctbase_genMatch: unknown type: %d\n", (int
)c1tid
));
1596 ** like ctbase_match
, except for conjuncts
:
1597 ** modifies conjuncts to match only
1601 ctbase_forceMatch
(ctbase c1
, ctbase c2
) /*@modifies c1
, c2@
*/
1603 return
(ctbase_genMatch
(c1
, c2
, TRUE, FALSE, FALSE, FALSE));
1607 ctbase_match
(ctbase c1
, ctbase c2
) /*@modifies nothing@
*/
1609 return
(ctbase_genMatch
(c1
, c2
, FALSE, FALSE, FALSE, FALSE));
1613 ctbase_matchDef
(ctbase c1
, ctbase c2
) /*@modifies nothing@
*/
1615 return
(ctbase_genMatch
(c1
, c2
, FALSE, FALSE, TRUE, FALSE));
1619 ctbase_matchArg
(ctbase c1
, ctbase c2
)
1621 return
(ctbase_genMatch
(c1
, c2
, FALSE, TRUE, FALSE, FALSE));
1624 static
/*@out@
*/ /*@only@
*/ /*@notnull@
*/ ctbase
1627 ctbase c
= (ctbase
) dmalloc
(sizeof
(*c
));
1631 if
(nctbases
% 100 == 0 && nctbases > lastnc)
1633 llmsg
(message
("ctbases: %d", nctbases
));
1640 static
/*@only@
*/ ctbase
1641 ctbase_createPrim
(cprim p
)
1643 ctbase c
= ctbase_new
();
1646 c-
>contents.prim
= p
;
1651 static
/*@observer@
*/ ctbase
1652 ctbase_getBool
(void
)
1654 /*@i@
*/ return ctbase_createBool
();
1658 ctbase_createBool
(void
)
1660 if
(!ctbase_isDefined
(ctbase_bool
))
1662 ctbase_bool
= ctbase_new
();
1663 ctbase_bool-
>type
= CT_BOOL
;
1664 ctbase_bool-
>contents.prim
= CTX_BOOL
;
1667 /*@
-retalias@
*/ /*@
-globstate@
*/
1669 /*@
=retalias@
*/ /*@
=globstate@
*/
1672 static
/*@only@
*/ ctbase
1673 ctbase_createUser
(typeId u
)
1675 ctbase c
= ctbase_new
();
1678 c-
>contents.tid
= u
;
1680 llassert
(typeId_isValid
(u
));
1685 static
/*@only@
*/ ctbase
1686 ctbase_createEnum
(/*@keep@
*/ cstring etag
, /*@keep@
*/ enumNameList emembers
)
1688 ctbase c
= ctbase_new
();
1692 if
(cstring_isUndefined
(etag
))
1694 llcontbuglit
("Undefined enum tag!");
1698 c-
>contents.cenum
= (tenum
) dmalloc
(sizeof
(*c-
>contents.cenum
));
1699 c-
>contents.cenum-
>tag
= etag
;
1700 c-
>contents.cenum-
>members
= emembers
;
1705 static
/*@observer@
*/ cstring
1706 ctbase_enumTag
(/*@notnull@
*/ ctbase ct
)
1708 return
(ct-
>contents.cenum-
>tag
);
1711 static
/*@only@
*/ ctbase
1712 ctbase_createAbstract
(typeId u
)
1714 ctbase c
= ctbase_new
();
1717 c-
>contents.tid
= u
;
1719 /* also check its abstract?
*/
1721 llassert
(typeId_isValid
(c-
>contents.tid
));
1726 static
/*@only@
*/ ctbase
1727 ctbase_createNumAbstract
(typeId u
)
1729 ctbase c
= ctbase_new
();
1731 c-
>type
= CT_NUMABST
;
1732 c-
>contents.tid
= u
;
1734 /* also check its abstract?
*/
1736 llassert
(typeId_isValid
(c-
>contents.tid
));
1740 static
/*@only@
*/ ctbase
1741 ctbase_createUnknown
(void
)
1743 if
(!ctbase_isDefined
(ctbase_unknown
))
1745 ctbase_unknown
= ctbase_new
();
1746 ctbase_unknown-
>type
= CT_UNKNOWN
;
1747 ctbase_unknown-
>contents.prim
= CTX_UNKNOWN
;
1750 /*@
-retalias@
*/ /*@
-globstate@
*/
1751 return ctbase_unknown
;
1752 /*@
=retalias@
*/ /*@
=globstate@
*/
1756 ** requires
: result is not assigned to b
1757 ** (should copy
, but no way to reclaim storage
)
1760 static
/*@only@
*/ ctbase
1761 ctbase_makePointer
(ctype b
)
1763 ctbase c
= ctbase_new
();
1766 c-
>contents.base
= b
;
1771 static
/*@only@
*/ ctbase
1772 ctbase_makeArray
(ctype b
)
1774 ctbase c
= ctbase_new
();
1777 c-
>contents.base
= b
;
1782 static
/*@notnull@
*/ /*@only@
*/ ctbase
1783 ctbase_makeFixedArray
(ctype b
, size_t size
)
1785 ctbase c
= ctbase_new
();
1787 c-
>type
= CT_FIXEDARRAY
;
1789 c-
>contents.farray
= (tfixed
) dmalloc
(sizeof
(*c-
>contents.farray
));
1790 c-
>contents.farray-
>base
= b
;
1791 c-
>contents.farray-
>size
= size
;
1797 ctbase_makeFunction
(ctype b
, /*@only@
*/ uentryList p
)
1799 ctbase c
= ctbase_new
();
1803 c-
>contents.fcn
= (cfcn
) dmalloc
(sizeof
(*c-
>contents.fcn
));
1805 if
(ctype_isFunction
(b
)) /* was
: && ctype_isPointer (b)) */
1810 if
(ctype_isPointer
(b
))
1812 ctb
= ctype_getCtbase
(ctype_baseArrayPtr
(b
));
1816 ctb
= ctype_getCtbase
(b
);
1819 llassertfatal
(ctbase_isDefined
(ctb
));
1820 llassert
(ctb-
>type
== CT_FCN
);
1822 rval
= ctype_makeFunction
(ctb-
>contents.fcn-
>rval
, p
);
1824 c-
>contents.fcn-
>rval
= rval
;
1825 c-
>contents.fcn-
>params
= uentryList_copy
(ctb-
>contents.fcn-
>params
); /* no copy before
*/
1829 c-
>contents.fcn-
>rval
= b
;
1830 c-
>contents.fcn-
>params
= uentryList_copy
(p
); /* no copy before
*/
1831 /*@
-branchstate@
*/ /* p is really released on this branch
*/
1835 ct
= cttable_addComplex
(c
);
1836 return
(ct
); /* was
: ctype_makePointer
(ct
)); */
1840 ctbase_makeNFFunction
(ctype b
, /*@only@
*/ uentryList p
)
1842 ctbase c
= ctbase_new
();
1846 c-
>contents.fcn
= (cfcn
) dmalloc
(sizeof
(*c-
>contents.fcn
));
1848 if
(ctype_isFunction
(b
)) /* was
&& ctype_isPointer (b)) */
1853 if
(ctype_isPointer
(b
))
1855 ctb
= ctype_getCtbase
(ctype_baseArrayPtr
(b
));
1859 ctb
= ctype_getCtbase
(b
);
1862 llassertfatal
(ctbase_isDefined
(ctb
));
1863 llassert
(ctb-
>type
== CT_FCN
);
1865 rval
= ctype_makeNFParamsFunction
(ctb-
>contents.fcn-
>rval
, p
);
1867 c-
>contents.fcn-
>rval
= rval
;
1868 c-
>contents.fcn-
>params
= uentryList_copy
(ctb-
>contents.fcn-
>params
);
1872 c-
>contents.fcn-
>rval
= b
;
1873 c-
>contents.fcn-
>params
= uentryList_copy
(p
);
1878 ct
= cttable_addComplex
(c
);
1879 return
(ct
); /* was
: ctype_makePointer
(ct
)); */
1882 static
/*@only@
*/ ctbase
1883 ctbase_makeLiveFunction
(ctype b
, /*@only@
*/ uentryList p
)
1885 ctbase c
= ctbase_new
();
1889 c-
>contents.fcn
= (cfcn
) dmalloc
(sizeof
(*c-
>contents.fcn
));
1890 c-
>contents.fcn-
>rval
= b
;
1891 c-
>contents.fcn-
>params
= p
;
1893 /*@
-mustfree@
*/ return
(c
); /*@
=mustfree@
*/
1896 static
/*@observer@
*/ /*@notnull@
*/ ctbase
1897 ctbase_realFunction
(/*@dependent@
*/ /*@notnull@
*/ ctbase c
)
1901 llassertfatal
(ctbase_isFunction
(c
));
1903 if
(c-
>type
== CT_FCN
)
1908 res
= ctype_getCtbase
(ctbase_baseArrayPtr
(c
));
1909 llassert
(ctbase_isDefined
(res
));
1911 if
(ctbase_isUA
(res
))
1913 res
= ctbase_realFunction
(ctbase_realType
(res
));
1920 ctbase_isFunction
(ctbase c
)
1922 llassertfatal
(c
!= ctbase_undefined
);
1924 if
(c-
>type
== CT_FCN
)
1929 if
(c-
>type
== CT_PTR
)
1933 fcn
= ctype_getCtbase
(ctbase_baseArrayPtr
(c
));
1934 if
(ctbase_isDefined
(fcn
))
1936 if
(ctbase_isUA
(fcn
))
1938 return ctbase_isFunction
(ctbase_realType
(fcn
));
1940 return fcn-
>type
== CT_FCN
;
1947 /* doesn't copy c1 and c2
*/
1949 static
/*@only@
*/ ctbase
1950 ctbase_makeConj
(ctype c1
, ctype c2
, bool isExplicit
)
1952 ctbase c
= ctbase_new
();
1956 c-
>contents.conj
= (tconj
) dmalloc
(sizeof
(*c-
>contents.conj
));
1957 c-
>contents.conj-
>a
= c1
;
1958 c-
>contents.conj-
>b
= c2
;
1959 c-
>contents.conj-
>isExplicit
= isExplicit
;
1964 static bool ctbase_isAnytype
(/*@notnull@
*/ ctbase b
)
1967 ** A unknown|dne conj is a special representation for an anytype.
1970 if
(b-
>type
== CT_CONJ
)
1973 return
(b-
>contents.conj-
>a
== ctype_unknown
1974 && b->contents.conj->b == ctype_dne);
1975 /*@noaccess ctype@
*/
1982 ctbase_getConjA
(/*@notnull@
*/ ctbase c
)
1984 llassert
(c-
>type
== CT_CONJ
);
1985 return
(c-
>contents.conj-
>a
);
1989 ctbase_getConjB
(/*@notnull@
*/ ctbase c
)
1991 llassert
(c-
>type
== CT_CONJ
);
1992 return
(c-
>contents.conj-
>b
);
1996 ctbase_isExplicitConj
(/*@notnull@
*/ ctbase c
)
1998 llassert
(c-
>type
== CT_CONJ
);
1999 return
(c-
>contents.conj-
>isExplicit
);
2002 static
/*@only@
*/ ctbase
2003 ctbase_createStruct
(/*@only@
*/ cstring n
, /*@only@
*/ uentryList f
)
2005 ctbase c
= ctbase_new
();
2007 c-
>type
= CT_STRUCT
;
2009 c-
>contents.su
= (tsu
) dmalloc
(sizeof
(*c-
>contents.su
));
2010 c-
>contents.su-
>name
= n
;
2011 c-
>contents.su-
>fields
= f
;
2016 static
/*@observer@
*/ uentryList
2017 ctbase_getuentryList
(/*@notnull@
*/ ctbase c
)
2019 c
= ctbase_realType
(c
);
2021 if
(!(c-
>type
== CT_STRUCT || c-
>type
== CT_UNION
))
2022 llfatalbug
(message
("ctbase_getuentryList: bad invocation: %q", ctbase_unparse
(c
)));
2024 return
(c-
>contents.su-
>fields
);
2028 ctbase_createUnion
(/*@keep@
*/ cstring n
, /*@only@
*/ uentryList f
)
2030 ctbase c
= ctbase_new
();
2034 c-
>contents.su
= (tsu
) dmalloc
(sizeof
(*c-
>contents.su
));
2035 c-
>contents.su-
>name
= n
;
2036 c-
>contents.su-
>fields
= f
;
2042 ctbase_baseArrayPtr
(/*@notnull@
*/ ctbase c
)
2045 c
= ctbase_realType
(c
);
2048 if
(ct
== CT_FIXEDARRAY
)
2050 return c-
>contents.farray-
>base
;
2054 llassert
(ctuid_isAP
(ct
));
2056 return c-
>contents.base
;
2061 ctbase_baseFunction
(/*@notnull@
*/ ctbase c
)
2064 c
= ctbase_realFunction
(c
);
2066 if
(c-
>type
!= CT_FCN
)
2068 llfatalbug
(message
("ctbase_baseFunction: bad call: %q", ctbase_unparse
(c
)));
2071 return
(c-
>contents.fcn-
>rval
);
2075 ctbase_argsFunction
(/*@notnull@
*/ ctbase c
)
2078 c
= ctbase_realFunction
(c
);
2080 if
(c-
>type
!= CT_FCN
)
2082 llfatalbug
(message
("ctbase_argsFunction: bad call: %q",
2083 ctbase_unparse
(c
)));
2085 return
(c-
>contents.fcn-
>params
);
2089 ctbase_baseisExpFcn
(ctype c
)
2092 c
= ctype_removePointers
(c
);
2094 cb
= ctype_getCtbase
(c
);
2095 llassertfatal
(ctbase_isDefined
(cb
));
2097 if
(cb-
>type
== CT_FCN
)
2099 c
= ctype_removePointers
(ctype_getReturnType
(c
));
2101 cb
= ctype_getCtbase
(c
);
2102 llassertfatal
(ctbase_isDefined
(cb
));
2104 return
(cb-
>type
== CT_EXPFCN
);
2110 ** ctbase_newBase behaves specially when p is a CONJ
:
2112 ** c
-> conj
(newBase
(c
, p.a
), p.b
)
2116 ctbase_newBase
(ctype c
, ctype p
)
2120 DPRINTF
(("New base: %s / %s", ctype_unparse
(c
), ctype_unparse
(p
)));
2122 if
(ctype_isUndefined
(c
) || ctype_isUnknown
(c
))
2127 cb
= ctype_getCtbase
(c
);
2129 if
(ctype_isConj
(p
))
2131 ctbase pb
= ctype_getCtbase
(p
);
2133 llassertfatal
(ctbase_isDefined
(pb
));
2135 if
(pb-
>contents.conj-
>isExplicit
)
2137 return
(ctype_makeExplicitConj
(ctype_newBase
(c
, pb-
>contents.conj-
>a
),
2138 pb-
>contents.conj-
>b
));
2143 return
(ctype_makeConj
(ctype_newBase
(c
, pb-
>contents.conj-
>a
),
2144 pb-
>contents.conj-
>b
));
2149 if
(ctbase_baseisExpFcn
(c
))
2151 return
(ctbase_newBaseExpFcn
(c
, p
));
2154 llassertfatal
(ctbase_isDefined
(cb
));
2174 cbn
= ctbase_newBase
(cb-
>contents.base
, p
);
2175 ret
= ctype_makePointer
(cbn
);
2180 return
(ctype_makeFixedArray
(ctbase_newBase
(cb-
>contents.farray-
>base
, p
),
2181 cb-
>contents.farray-
>size
));
2183 return
(ctype_makeArray
(ctbase_newBase
(cb-
>contents.base
, p
)));
2185 return
(ctype_makeRawFunction
(ctbase_newBase
(cb-
>contents.fcn-
>rval
, p
),
2186 uentryList_copy
(cb-
>contents.fcn-
>params
)));
2188 return
(ctype_makeConjAux
(ctbase_newBase
(cb-
>contents.conj-
>a
, p
),
2189 ctbase_newBase
(cb-
>contents.conj-
>b
, p
),
2190 cb-
>contents.conj-
>isExplicit
));
2192 llcontbug
(message
("ctbase_newBase: bad ctbase: %q", ctbase_unparse
(cb
)));
2199 ctbase_newBaseExpFcn
(ctype c
, ctype p
)
2201 ctbase cb
= ctype_getCtbase
(c
);
2204 ctype fp
= ctype_unknown
;
2205 uentryList ctargs
= ctype_argsFunction
(c
);
2208 ** okay
, this is really ugly...
2210 ** pointers inside
<expf
> mean pointers to the function
;
2211 ** pointers outside
<expf
> are pointers to the return value
;
2212 ** because its a function there is one superfluous pointer.
2216 ** bf is a ctype
, used to derived structure of cb
2219 if
(!ctbase_isFunction
(cb
))
2220 llbuglit
("ctbase_newBaseExpFcn: expFcn -> not a function");
2222 tmpct
= ctype_getBaseType
(ctype_getReturnType
(c
));
2225 ** pointers before expfcn
-> p are pointers to function
, not result
2229 tcb
= ctype_getCtbase
(tmpct
);
2231 llassertfatal
(ctbase_isDefined
(tcb
));
2232 tmpct
= tcb-
>contents.base
;
2235 ** record pointers to base in fp
2238 while
(!ctype_isUnknown
(tmpct
))
2240 if
(ctype_isExpFcn
(tmpct
)) {
2241 ctbase ttcb
= ctype_getCtbase
(tmpct
);
2244 ** evs
2000-05-16: This is necessary to deal with function pointers in parens.
2245 ** The whole function pointer parsing is a major kludge
, but it seems to work
,
2246 ** and I'm only embarrassed by it when I haven't look at the C spec recently...
2249 llassertfatal
(ctbase_isDefined
(ttcb
));
2250 tmpct
= ttcb-
>contents.base
;
2251 llassert
(!ctype_isUnknown
(tmpct
));
2254 switch
(ctype_getCtKind
(tmpct
))
2257 fp
= ctype_makePointer
(fp
);
2258 /*@switchbreak@
*/ break
;
2260 fp
= ctype_makeArray
(fp
);
2261 /*@switchbreak@
*/ break
;
2264 ctbase fbase
= ctype_getCtbase
(tmpct
);
2266 if
(ctbase_isFunction
(fbase
))
2268 fp
= ctype_makeFunction
(fp
, uentryList_copy
(ctargs
));
2269 ctargs
= ctbase_argsFunction
(fbase
);
2275 ("ctbase_newBaseExpFcn: fixing expfunction: bad complex type: %s [base: %q]",
2276 ctype_unparse
(tmpct
), ctbase_unparse
(fbase
)));
2283 (message
("ctbase_newBaseExpFcn: fixing expfunction: bad type: %s",
2284 ctype_unparse
(tmpct
)));
2288 tmpct
= ctype_baseArrayPtr
(tmpct
);
2292 tmpct
= ctype_getReturnType
(c
);
2295 ** pointers to expf are pointers to return value
2298 while
(!ctype_isExpFcn
(tmpct
))
2300 switch
(ctype_getCtKind
(tmpct
))
2303 p
= ctype_makePointer
(p
);
2304 /*@switchbreak@
*/ break
;
2306 p
= ctype_makeArray
(p
);
2307 /*@switchbreak@
*/ break
;
2310 ctbase fbase
= ctype_getCtbase
(tmpct
);
2312 if
(ctbase_isFunction
(fbase
))
2314 p
= ctype_makeFunction
(p
, uentryList_copy
(ctbase_argsFunction
(fbase
)));
2320 ("ctbase_newBaseExpFcn: fixing expfunction: bad complex type: %s",
2321 ctype_unparse
(tmpct
)));
2329 (message
("ctbase_newBaseExpFcn: fixing expfunction2: bad type: %t",
2334 tmpct
= ctype_baseArrayPtr
(tmpct
);
2340 ** pointers to fp are pointers to function type
2343 ret
= ctype_makeRawFunction
(p
, uentryList_copy
(ctargs
));
2345 while
(ctype_getCtKind
(fp
) > CTK_PLAIN
)
2347 switch
(ctype_getCtKind
(fp
))
2350 ret
= ctype_makePointer
(ret
);
2351 /*@switchbreak@
*/ break
;
2353 ret
= ctype_makeArray
(ret
);
2354 /*@switchbreak@
*/ break
;
2357 ctbase fbase
= ctype_getCtbase
(fp
);
2359 if
(ctbase_isFunction
(fbase
))
2362 ctype_makeFunction
(ret
,
2363 uentryList_copy
(ctbase_argsFunction
(fbase
)));
2374 llcontbug
(message
("post-fixing expfunction: bad type: %t", fp
));
2378 fp
= ctype_baseArrayPtr
(fp
);
2387 ** returns lowest level base of c
: plain type
2390 static
/*@notnull@
*/ /*@only@
*/ ctbase
2391 ctbase_getBaseType
(/*@notnull@
*/ ctbase c
)
2406 return
(ctbase_copy
(c
));
2410 return
(ctbase_getBaseType
(ctype_getCtbaseSafe
(c-
>contents.base
)));
2413 return
(ctbase_getBaseType
(ctype_getCtbaseSafe
(c-
>contents.farray-
>base
)));
2414 case CT_CONJ
: /* base type of A conj branch?
*/
2415 return
(ctbase_getBaseType
(ctype_getCtbaseSafe
(c-
>contents.conj-
>a
)));
2417 return
(ctbase_copy
(c
));
2420 llfatalbug
(message
("ctbase_getBaseType: bad ctbase: %q", ctbase_unparse
(c
)));
2428 ctbase_compare
(ctbase c1
, ctbase c2
, bool strict
)
2432 if
(ctbase_isUndefined
(c1
) || ctbase_isUndefined
(c2
))
2434 llcontbuglit
("ctbase_compare: undefined ctbase");
2451 return
(int_compare
(c1-
>contents.prim
, c2-
>contents.prim
));
2455 return
(typeId_compare
(c1-
>contents.tid
, c2-
>contents.tid
));
2458 case CT_ENUM
: /* for now
, keep like abstract
*/
2461 return
(typeId_compare
(c1-
>contents.tid
, c2-
>contents.tid
));
2463 return
(ctype_compare
(c1-
>contents.base
, c2-
>contents.base
));
2465 INTCOMPARERETURN
(c1-
>contents.farray-
>size
, c2-
>contents.farray-
>size
);
2467 return
(ctype_compare
(c1-
>contents.farray-
>base
,
2468 c2-
>contents.farray-
>base
));
2470 return
(ctype_compare
(c1-
>contents.base
, c2-
>contents.base
));
2473 COMPARERETURN
(ctype_compare
(c1-
>contents.fcn-
>rval
, c2-
>contents.fcn-
>rval
));
2477 return
(uentryList_compareStrict
(c1-
>contents.fcn-
>params
,
2478 c2-
>contents.fcn-
>params
));
2482 return
(uentryList_compareParams
(c1-
>contents.fcn-
>params
,
2483 c2-
>contents.fcn-
>params
));
2487 return
(ctype_compare
(c1-
>contents.base
, c2-
>contents.base
));
2490 /* evs
2000-07-28: this block was missing
! */
2492 int ncmp
= cstring_compare
(c1-
>contents.su-
>name
,
2493 c2-
>contents.su-
>name
);
2496 if
(isFakeTag
(c1-
>contents.su-
>name
)
2497 && isFakeTag (c2->contents.su->name)) {
2498 ; /* If they are both fake struct tags
, don't require match.
*/
2505 DPRINTF
(("Comparing fields: %s / %s",
2506 ctbase_unparse
(c1
),
2507 ctbase_unparse
(c2
)));
2509 return
(uentryList_compareFields
(c1-
>contents.su-
>fields
,
2510 c2-
>contents.su-
>fields
));
2513 COMPARERETURN
(ctype_compare
(c1-
>contents.conj-
>a
,
2514 c2-
>contents.conj-
>a
));
2515 COMPARERETURN
(ctype_compare
(c1-
>contents.conj-
>b
,
2516 c2-
>contents.conj-
>b
));
2517 return
(bool_compare
(c1-
>contents.conj-
>isExplicit
,
2518 c2-
>contents.conj-
>isExplicit
));
2525 ctbase_compareStrict
(/*@notnull@
*/ ctbase c1
, /*@notnull@
*/ ctbase c2
)
2527 return
(ctbase_compare
(c1
, c2
, TRUE));
2530 static bool ctbase_equivStrict
(/*@notnull@
*/ ctbase c1
, /*@notnull@
*/ ctbase c2
)
2532 return
(ctbase_compareStrict
(c1
,c2
) == 0);
2535 static bool ctbase_equiv
(/*@notnull@
*/ ctbase c1
, /*@notnull@
*/ ctbase c2
)
2537 return
(ctbase_compare
(c1
, c2
, FALSE) == 0);
2541 ctbase_isKind
(/*@notnull@
*/ ctbase c
, ctuid kind
)
2549 return
(ctbase_isKind
(ctype_getCtbaseSafe
(c-
>contents.conj-
>a
), kind
) ||
2550 ctbase_isKind
(ctype_getCtbaseSafe
(c-
>contents.conj-
>b
), kind
));
2557 ctbase_isKind2
(/*@notnull@
*/ ctbase c
, ctuid kind1
, ctuid kind2
)
2561 if
(ck
== kind1 || ck
== kind2
)
2565 return
(ctbase_isKind2
(ctype_getCtbaseSafe
(c-
>contents.conj-
>a
), kind1
, kind2
) ||
2566 ctbase_isKind2
(ctype_getCtbaseSafe
(c-
>contents.conj-
>b
), kind1
, kind2
));
2573 ctbase_isAbstract
(/*@notnull@
*/ ctbase c
)
2575 return
(c-
>type
== CT_ABST || c-
>type
== CT_NUMABST
);
2579 ctbase_isNumAbstract
(/*@notnull@
*/ ctbase c
)
2581 return
(c-
>type
== CT_NUMABST
);
2584 static bool ctbase_isUA
(ctbase c
)
2586 return
(ctbase_isDefined
(c
) && (ctuid_isAnyUserType (c->type)));
2590 ctbase_almostEqual
(ctbase c1
, ctbase c2
)
2594 /* undefined types never match
*/
2596 if
(ctbase_isUndefined
(c1
) || ctbase_isUndefined
(c2
))
2602 if
(c1tid
== CT_FIXEDARRAY
&& c2tid == CT_ARRAY)
2604 return
(ctbase_almostEqual
(ctype_getCtbase
(c1-
>contents.farray-
>base
),
2605 ctype_getCtbase
(c2-
>contents.base
)));
2608 if
(c2tid
== CT_FIXEDARRAY
&& c1tid == CT_ARRAY)
2610 return
(ctbase_almostEqual
(ctype_getCtbase
(c1-
>contents.base
),
2611 ctype_getCtbase
(c2-
>contents.farray-
>base
)));
2622 return
(cprim_equal
(c1-
>contents.prim
, c2-
>contents.prim
));
2628 return
(typeId_equal
(c1-
>contents.tid
, c2-
>contents.tid
));
2630 return
(cstring_equal
(c1-
>contents.cenum-
>tag
, c2-
>contents.cenum-
>tag
));
2632 return
(ctype_almostEqual
(c1-
>contents.base
, c2-
>contents.base
));
2634 return
(ctype_almostEqual
(c1-
>contents.farray-
>base
,
2635 c2-
>contents.farray-
>base
));
2637 return
(ctype_almostEqual
(c1-
>contents.base
, c2-
>contents.base
));
2639 return
(ctype_almostEqual
(c1-
>contents.fcn-
>rval
, c2-
>contents.fcn-
>rval
)
2640 && uentryList_matchParams (c1->contents.fcn->params,
2641 c2-
>contents.fcn-
>params
, FALSE, TRUE));
2644 if
(!cstring_isEmpty
(c1-
>contents.su-
>name
))
2646 return
(cstring_equal
(c1-
>contents.su-
>name
, c2-
>contents.su-
>name
));
2650 if
(!cstring_isEmpty
(c2-
>contents.su-
>name
))
2655 llcontbuglit
("ctbase_almostEqual: match fields");
2659 llcontbug
(message
("ctbase_almostEqual: unknown type: %d\n", (int
)c1tid
));
2664 /*drl added July
02, 001
2665 called by ctype_getArraySize
2668 static size_t ctbase_getArraySize
(ctbase ctb
)
2670 /*drl
1/25/2002 fixed discovered by Jim Francis
*/
2673 llassert
(ctbase_isDefined
(ctb
));
2674 r
= ctbase_realType
(ctb
);
2675 llassert
(ctbase_isFixedArray
(r
));
2677 return
(r-
>contents.farray-
>size
);
2680 static bool ctbase_isBigger
(ctbase ct1
, ctbase ct2
)
2682 if
(ct1
!= NULL && ct2 != NULL
2683 && (ct1->type == CT_PRIM && ct2->type == CT_PRIM))
2685 /* Only compare sizes for primitives
*/
2686 cprim cp1
= ct1-
>contents.prim
;
2687 cprim cp2
= ct2-
>contents.prim
;
2688 int nbits1
= cprim_getExpectedBits
(cp1
);
2689 int nbits2
= cprim_getExpectedBits
(cp2
);
2691 if
(nbits1
> nbits2
) {
2703 static int ctbase_getSize
(ctbase ct
)
2716 cprim cp
= ct-
>contents.prim
;
2717 int nbits
= cprim_getExpectedBits
(cp
);
2729 /* Malloc returns void
*, but they are bytes. Normal void
* is pointer size.
*/
2730 if
(ctype_isVoid
(ct-
>contents.base
))
2736 return ctype_getSize
(ct-
>contents.base
);