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
/*@only@
*/ /*@notnull@
*/ ctbase ctbase_copy
(/*@notnull@
*/ ctbase p_c
) /*@
*/ ;
116 static void ctbase_free
(/*@only@
*/ ctbase p_c
);
117 static
/*@notnull@
*/ /*@only@
*/ ctbase ctbase_createPrim
(cprim p_p
) /*@
*/ ;
118 static
/*@notnull@
*/ /*@only@
*/ ctbase ctbase_createBool
(void
) /*@
*/ ;
119 static
/*@notnull@
*/ /*@observer@
*/ ctbase ctbase_getBool
(void
) /*@
*/ ;
120 static
/*@notnull@
*/ /*@only@
*/ ctbase ctbase_createUser
(typeId p_u
) /*@
*/ ;
122 static
/*@notnull@
*/ /*@only@
*/ ctbase
123 ctbase_createStruct
(/*@only@
*/ cstring p_n
, /*@only@
*/ uentryList p_f
);
125 static
/*@notnull@
*/ /*@only@
*/ ctbase
126 ctbase_createUnion
(/*@keep@
*/ cstring p_n
, /*@only@
*/ uentryList p_f
);
127 static
/*@notnull@
*/ /*@only@
*/ ctbase ctbase_createEnum
(/*@keep@
*/ cstring p_etag
, /*@keep@
*/ enumNameList p_emembers
);
128 static
/*@notnull@
*/ /*@only@
*/ ctbase ctbase_createUnknown
(void
);
129 static bool ctbase_match
(ctbase p_c1
, ctbase p_c2
) /*@modifies nothing@
*/;
130 static bool ctbase_matchDef
(ctbase p_c1
, ctbase p_c2
) /*@modifies nothing@
*/;
131 static bool ctbase_genMatch
(ctbase p_c1
, ctbase p_c2
, bool p_force
, bool p_arg
, bool p_def
, bool p_deep
);
132 static bool ctbase_isAbstract
(/*@notnull@
*/ ctbase p_c
) /*@
*/ ;
133 static
/*@notnull@
*/ /*@only@
*/ ctbase ctbase_makePointer
(ctype p_b
) /*@
*/ ;
134 static
/*@notnull@
*/ /*@only@
*/ ctbase ctbase_makeArray
(ctype p_b
) /*@
*/ ;
135 static
/*@notnull@
*/ ctype
136 ctbase_makeFunction
(ctype p_b
, /*@only@
*/ uentryList p_p
) /*@
*/ ;
137 static
/*@notnull@
*/ /*@observer@
*/ ctbase
138 ctbase_realFunction
(/*@notnull@
*/ /*@dependent@
*/ ctbase p_c
) /*@
*/ ;
139 static ctype ctbase_baseArrayPtr
(/*@notnull@
*/ ctbase p_c
) /*@
*/ ;
140 static ctype ctbase_baseFunction
(/*@notnull@
*/ ctbase p_c
) /*@
*/ ;
141 static
/*@observer@
*/ uentryList ctbase_argsFunction
(/*@notnull@
*/ ctbase p_c
) /*@
*/ ;
142 static
/*@observer@
*/ uentryList ctbase_getuentryList
(/*@notnull@
*/ ctbase p_c
) /*@
*/ ;
143 static ctype ctbase_newBase
(ctype p_c
, ctype p_p
) /*@
*/ ;
144 static ctype ctbase_newBaseExpFcn
(ctype p_c
, ctype p_p
) /*@
*/ ;
145 static bool ctbase_isFixedArray
(/*@notnull@
*/ ctbase p_c
) /*@
*/ ;
148 extern int cttable_lastIndex
();
149 # define cttable_lastIndex
() (cttab.size
- 1)
155 /*@only@
*/ uentryList params
;
174 enumNameList members
;
185 cprim prim
; /* primitive
*/
186 typeId tid
; /* abstract
, user
*/
187 ctype base
; /* ptr
, array
*/
188 cfcn fcn
; /* function
*/
189 tsu su
; /* struct union
*/
190 tenum cenum
; /* enum
*/
191 tconj conj
; /* conj
*/
192 tfixed farray
; /* fixed array
*/
201 static
/*@falsenull@
*/ bool ctbase_isUA
(ctbase p_c
) /*@
*/ ;
202 static bool ctbase_isBaseUA
(ctbase p_c
) /*@
*/ ;
203 static typeId ctbase_typeBaseUid
(ctbase p_c
) /*@
*/ ;
204 static bool ctbase_isKind
(/*@notnull@
*/ ctbase p_c
, ctuid p_kind
) /*@
*/ ;
205 static bool ctbase_isKind2
(/*@notnull@
*/ ctbase p_c
, ctuid p_kind1
, ctuid p_kind2
) /*@
*/ ;
206 static
/*@only@
*/ /*@notnull@
*/ ctbase
207 ctbase_getBaseType
(/*@notnull@
*/ ctbase p_c
) /*@
*/ ;
209 static
/*@falsenull@
*/ bool ctbase_isFunction
(ctbase p_c
) /*@
*/ ;
211 /*@constant null ctbase ctbase_undefined
; @
*/
212 # define ctbase_undefined
((ctbase
)0)
214 static
/*@owned@
*/ ctbase ctbase_bool
= ctbase_undefined
;
215 static
/*@owned@
*/ ctbase ctbase_unknown
= ctbase_undefined
;
217 static
/*@falsenull@
*/ bool ctbase_isDefined
(ctbase c
) /*@
*/
219 return
((c
) != ctbase_undefined
);
222 static
/*@truenull@
*/ bool ctbase_isUndefined
(ctbase c
)
224 return
((c
) == ctbase_undefined
);
227 static ctkind ctype_getCtKind
(ctype c
)
229 ctentry ce
= ctype_getCtentry
(c
);
231 return ctentry_getKind
(ce
);
234 static bool ctbase_isUser
(ctbase c
)
236 if
(ctbase_isDefined
(c
))
238 return
(ctbase_isKind
(c
, CT_USER
));
246 static bool ctbase_isEnum
(ctbase c
)
248 if
(ctbase_isDefined
(c
))
250 return
(ctbase_isKind
(c
, CT_ENUM
));
258 static bool ctbase_isExpFcn
(ctbase c
)
260 if
(ctbase_isDefined
(c
))
262 return
(c-
>type
== CT_EXPFCN
);
270 static
/*@falsenull@
*/ bool ctbase_isConj
(ctbase c
)
272 if
(ctbase_isDefined
(c
))
274 return
(c-
>type
== CT_CONJ
);
282 static bool ctuid_isAP
(ctuid c
) /*@
*/
284 return
(c
== CT_ARRAY || c
== CT_PTR
);
287 static typeId ctbase_typeId
(ctbase p_c
);
288 static
/*@only@
*/ cstring ctbase_dump
(ctbase p_c
);
289 static
/*@only@
*/ ctbase ctbase_undump
(char
**p_c
) /*@requires maxRead
(*p_c
) >= 2 @
*/;
290 static int ctbase_compare
(ctbase p_c1
, ctbase p_c2
, bool p_strict
);
291 static bool ctbase_matchArg
(ctbase p_c1
, ctbase p_c2
);
292 static
/*@notnull@
*/ /*@only@
*/ ctbase
293 ctbase_makeConj
(ctype p_c1
, ctype p_c2
, bool p_isExplicit
) /*@
*/ ;
294 static ctype ctbase_getConjA
(/*@notnull@
*/ ctbase p_c
) /*@
*/ ;
295 static ctype ctbase_getConjB
(/*@notnull@
*/ ctbase p_c
) /*@
*/ ;
296 static bool ctbase_isExplicitConj
(/*@notnull@
*/ ctbase p_c
) /*@
*/ ;
297 static bool ctbase_forceMatch
(ctbase p_c1
, ctbase p_c2
) /*@modifies p_c1
, p_c2@
*/ ;
298 static
/*@notnull@
*/ /*@only@
*/ ctbase ctbase_expectFunction
(ctype p_c
);
299 static bool ctbase_isVoidPointer
(/*@notnull@
*/ /*@dependent@
*/ ctbase p_c
) /*@
*/ ;
300 static bool ctbase_isUnion
(/*@notnull@
*/ /*@temp@
*/ ctbase p_c
) /*@
*/ ;
301 static bool ctbase_isStruct
(/*@notnull@
*/ /*@temp@
*/ ctbase p_c
) /*@
*/ ;
302 static
/*@observer@
*/ cstring ctbase_enumTag
(/*@notnull@
*/ ctbase p_ct
) /*@
*/ ;
303 static
/*@only@
*/ cstring ctbase_unparseNotypes
(ctbase p_c
) /*@
*/ ;
305 static
/*@out@
*/ /*@notnull@
*/ /*@only@
*/ ctbase ctbase_new
(void
) /*@
*/ ;
306 static int nctbases
= 0;
308 static
/*@notnull@
*/ /*@only@
*/
309 ctbase ctbase_makeLiveFunction
(ctype p_b
, /*@only@
*/ uentryList p_p
);
311 static bool ctbase_isUnnamedSU
(ctbase c
)
313 return
(ctbase_isDefined
(c
)
314 && (ctbase_isStruct (c) || ctbase_isUnion (c))
315 && isFakeTag (c->contents.su->name));
318 static
/*@observer@
*/ ctbase ctbase_realType
(ctbase c
)
322 typeId uid
= ctbase_typeId
(c
);
324 if
(usymtab_isBoolType
(uid
))
326 return ctbase_getBool
();
330 ctbase ret
= ctype_getCtbase
331 (uentry_getRealType
(usymtab_getTypeEntry
(ctbase_typeId
(c
))));
333 llassert
(ret
!= ctbase_undefined
);
344 ctbase_isVoidPointer
(/*@dependent@
*/ /*@notnull@
*/ ctbase c
)
346 ctbase r
= ctbase_realType
(c
);
348 return
(ctbase_isKind
(r
, CT_PTR
) &&
349 ctype_isVoid
(r-
>contents.base
));
353 ctbase_isPointer
(/*@notnull@
*/ /*@dependent@
*/ ctbase c
)
355 ctbase r
= ctbase_realType
(c
);
357 return
(ctbase_isKind
(r
, CT_PTR
));
361 ctbase_isEitherArray
(/*@notnull@
*/ ctbase c
)
363 ctbase r
= ctbase_realType
(c
);
365 return
(ctbase_isKind
(r
, CT_ARRAY
)
366 || ctbase_isKind
(r
, CT_FIXEDARRAY
));
370 ctbase_isFixedArray
(/*@notnull@
*/ ctbase c
)
372 ctbase r
= ctbase_realType
(c
);
374 return
(ctbase_isKind
(r
, CT_FIXEDARRAY
));
378 ctbase_isStruct
(/*@notnull@
*/ ctbase c
)
380 ctbase r
= ctbase_realType
(c
);
382 return
(ctbase_isKind
(r
, CT_STRUCT
));
386 ctbase_isUnion
(/*@notnull@
*/ ctbase c
)
388 ctbase r
= ctbase_realType
(c
);
390 return
(ctbase_isKind
(r
, CT_UNION
));
394 ** clean this up
-> typeTable should store ctype
398 ctbase_typeBaseUid
(ctbase c
)
402 if
(ctbase_isDefined
(c
))
408 return ctbase_typeBaseUid
(ctype_getCtbase
(c-
>contents.base
));
410 else if
(ct
== CT_USER || ct
== CT_ABST || ct
== CT_NUMABST
)
412 return c-
>contents.tid
;
414 else if
(ct
== CT_FIXEDARRAY
)
416 return ctbase_typeBaseUid
(ctype_getCtbase
(c-
>contents.farray-
>base
));
420 llcontbuglit
("ctbase_typeBaseUid: bad call");
421 return typeId_invalid
;
424 return typeId_invalid
;
428 ctbase_isBaseUA
(ctbase c
)
432 if
(ctbase_isDefined
(c
))
438 return ctbase_isBaseUA
(ctype_getCtbase
(c-
>contents.base
));
440 else if
(ct
== CT_FIXEDARRAY
)
442 return ctbase_isBaseUA
(ctype_getCtbase
(c-
>contents.farray-
>base
));
445 return
(ct
== CT_USER || ct
== CT_ABST || ct
== CT_NUMABST
);
451 ctbase_typeId
(ctbase c
)
455 return c-
>contents.tid
;
459 if
(ctbase_isConj
(c
))
461 if
(ctype_isUA
(ctbase_getConjA
(c
))) {
462 return ctbase_typeId
(ctype_getCtbase
(ctbase_getConjA
(c
)));
463 } else if
(ctype_isUA
(ctbase_getConjB
(c
))) {
464 return ctbase_typeId
(ctype_getCtbase
(ctbase_getConjB
(c
)));
466 llcontbug
(message
("ctbase_typeId: bad call: %q", ctbase_unparse
(c
)));
467 return typeId_invalid
;
472 llcontbug
(message
("ctbase_typeId: bad call: %q", ctbase_unparse
(c
)));
473 return typeId_invalid
;
478 static
/*@only@
*/ cstring
479 ctbase_unparse
(ctbase c
)
481 if
(ctbase_isUndefined
(c
)) {
482 return cstring_makeLiteral
("<<undef>>");
488 return cstring_makeLiteral
("?");
490 return cstring_copy
(context_printBoolName
());
492 return
(cprim_unparse
(c-
>contents.prim
));
496 return
(usymtab_getTypeEntryName
(c-
>contents.tid
));
498 return
(message
("<expf: %t>", c-
>contents.base
));
500 /* no spaces for multiple pointers
*/
502 if
(ctype_isPointer
(c-
>contents.base
))
504 return
(cstring_appendChar
(cstring_copy
(ctype_unparse
(c-
>contents.base
)), '
*'
));
508 return
(message
("%t *", c-
>contents.base
));
512 ** C prints out array declarations backwards
, if
513 ** base is an array need to print out in reverse order.
516 if
(ctype_isArray
(c-
>contents.farray-
>base
))
518 ctype base
= c-
>contents.farray-
>base
;
519 cstring res
= message
("[%d]", (int
) c-
>contents.farray-
>size
);
521 while
(ctype_isArray
(base
))
523 if
(ctype_isFixedArray
(base
))
525 res
= message
("%q[%d]",
526 res
, (int
) ctype_getArraySize
(base
));
530 res
= message
("%q[]", res
);
533 base
= ctype_baseArrayPtr
(base
);
536 return
(message
("%t %q", base
, res
));
540 return
(message
("%t [%d]",
541 c-
>contents.farray-
>base
,
542 (int
) c-
>contents.farray-
>size
));
545 if
(ctype_isArray
(c-
>contents.base
))
547 ctype base
= c-
>contents.base
;
548 cstring res
= cstring_makeLiteral
("[]");
550 while
(ctype_isArray
(base
))
552 if
(ctype_isFixedArray
(base
))
554 res
= message
("%q[%d]",
555 res
, (int
) ctype_getArraySize
(base
));
559 res
= message
("%q[]", res
);
562 base
= ctype_baseArrayPtr
(base
);
565 return
(message
("%t %q", base
, res
));
570 return
(message
("%t []", c-
>contents.base
));
573 return
(message
("[function (%q) returns %t]",
574 uentryList_unparseParams
(c-
>contents.fcn-
>params
),
575 c-
>contents.fcn-
>rval
));
577 if
(cstring_isDefined
(c-
>contents.su-
>name
) &&
578 !cstring_isEmpty
(c-
>contents.su-
>name
) &&
579 !isFakeTag
(c-
>contents.su-
>name
))
581 return
(message
("struct %s", c-
>contents.su-
>name
));
585 return
(message
("struct { %q }",
586 uentryList_unparseAbbrev
(c-
>contents.su-
>fields
)));
589 if
(cstring_isDefined
(c-
>contents.su-
>name
) &&
590 !cstring_isEmpty
(c-
>contents.su-
>name
) &&
591 !isFakeTag
(c-
>contents.su-
>name
))
593 return
(message
("union %s", c-
>contents.su-
>name
));
597 return
(message
("union { %q }",
598 uentryList_unparseAbbrev
(c-
>contents.su-
>fields
)));
601 if
(isFakeTag
(c-
>contents.cenum-
>tag
))
603 return
(message
("enum { %q }",
604 enumNameList_unparseBrief
(c-
>contents.cenum-
>members
)));
608 return
(message
("enum %s { %q }",
609 c-
>contents.cenum-
>tag
,
610 enumNameList_unparseBrief
(c-
>contents.cenum-
>members
)));
613 if
(ctbase_isAnytype
(c
))
615 return
(cstring_makeLiteral
("<any>"));
617 else if
(c-
>contents.conj-
>isExplicit || context_getFlag
(FLG_SHOWALLCONJS
))
619 if
(!ctype_isSimple
(c-
>contents.conj-
>a
) ||
620 !ctype_isSimple
(c-
>contents.conj-
>b
))
622 return
(message
("<%t> | <%t>", c-
>contents.conj-
>a
, c-
>contents.conj-
>b
));
626 return
(message
("%t | %t", c-
>contents.conj-
>a
, c-
>contents.conj-
>b
));
631 return
(cstring_copy
(ctype_unparse
(c-
>contents.conj-
>a
)));
638 static
/*@only@
*/ cstring
639 ctbase_unparseDeep
(ctbase c
)
641 if
(ctbase_isUndefined
(c
))
643 return cstring_makeLiteral
("<<undef>>");
649 return cstring_makeLiteral
("?");
651 return cstring_copy
(context_printBoolName
());
653 return
(cprim_unparse
(c-
>contents.prim
));
655 if
(cstring_isNonEmpty
(c-
>contents.cenum-
>tag
))
657 return
(message
("enum %s { %q }",
658 c-
>contents.cenum-
>tag
,
659 enumNameList_unparse
(c-
>contents.cenum-
>members
)));
663 return
(message
("enum { %q }",
664 enumNameList_unparse
(c-
>contents.cenum-
>members
)));
669 return
(usymtab_getTypeEntryName
(c-
>contents.tid
));
671 return
(message
("<expf: %t>", c-
>contents.base
));
673 return
(message
("%t *", c-
>contents.base
));
675 return
(message
("%t [%d]", c-
>contents.farray-
>base
,
676 (int
) c-
>contents.farray-
>size
));
678 return
(message
("%t []", c-
>contents.base
));
680 return
(message
("[function (%q) returns %t]",
681 uentryList_unparse
(c-
>contents.fcn-
>params
),
682 c-
>contents.fcn-
>rval
));
684 return
(message
("struct %s { ... } ", c-
>contents.su-
>name
));
686 return
(message
("union %s { ... }", c-
>contents.su-
>name
));
688 if
(ctbase_isAnytype
(c
))
690 return
(cstring_makeLiteral
("<any>"));
694 return
(message
("%t", c-
>contents.conj-
>a
));
701 static
/*@only@
*/ cstring
702 ctbase_unparseNotypes
(ctbase c
)
704 llassert
(ctbase_isDefined
(c
));
709 return cstring_makeLiteral
("?");
711 return cstring_copy
(context_printBoolName
());
713 return
(cprim_unparse
(c-
>contents.prim
));
715 if
(typeId_isInvalid
(c-
>contents.tid
))
717 return cstring_makeLiteral
("enum");
721 return
(message
("T#%d", c-
>contents.tid
));
724 return
(message
("uT#%d", c-
>contents.tid
));
726 return
(message
("aT#%d", c-
>contents.tid
));
728 return
(message
("nT#%d", c-
>contents.tid
));
730 return
(message
("<expf: %q >", ctbase_unparseNotypes
(ctype_getCtbase
(c-
>contents.base
))));
732 return
(message
("%q *", ctbase_unparseNotypes
(ctype_getCtbase
(c-
>contents.base
))));
734 return
(message
("%q []", ctbase_unparseNotypes
(ctype_getCtbase
(c-
>contents.base
))));
736 return
(message
("[function (%d) returns %q]", uentryList_size
(c-
>contents.fcn-
>params
),
737 ctbase_unparseNotypes
(ctype_getCtbase
(c-
>contents.fcn-
>rval
))));
739 return
(message
("struct %s", c-
>contents.su-
>name
));
741 return
(message
("union %s", c-
>contents.su-
>name
));
743 return
(message
("[enumlist]"));
745 if
(ctbase_isAnytype
(c
))
747 return
(cstring_makeLiteral
("<any>"));
751 return
(message
("%q/%q",
752 ctbase_unparseNotypes
(ctype_getCtbase
(c-
>contents.conj-
>a
)),
753 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 llassert
(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 llassert
(lc
!= NULL);
988 sname
= mstring_copy
(*c
);
989 llassert
(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 llassert
(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"));
1147 static
/*@only@
*/ ctbase
1148 ctbase_copy
(/*@notnull@
*/ ctbase c
)
1153 return
(ctbase_createUnknown
());
1155 return
(ctbase_createBool
());
1157 return
(ctbase_createEnum
(cstring_copy
(c-
>contents.cenum-
>tag
),
1158 enumNameList_copy
(c-
>contents.cenum-
>members
)));
1160 return
(ctbase_createPrim
(c-
>contents.prim
));
1162 return
(ctbase_createUser
(c-
>contents.tid
));
1164 return
(ctbase_createAbstract
(c-
>contents.tid
));
1166 return
(ctbase_createNumAbstract
(c-
>contents.tid
));
1168 return
(ctbase_expectFunction
(c-
>contents.base
));
1170 return
(ctbase_makePointer
(c-
>contents.base
));
1172 return
(ctbase_makeArray
(c-
>contents.base
));
1174 return
(ctbase_makeLiveFunction
(c-
>contents.fcn-
>rval
,
1175 uentryList_copy
(c-
>contents.fcn-
>params
)));
1177 return
(ctbase_createStruct
(cstring_copy
(c-
>contents.su-
>name
),
1178 uentryList_copy
(c-
>contents.su-
>fields
)));
1180 return
(ctbase_createUnion
(cstring_copy
(c-
>contents.su-
>name
),
1181 uentryList_copy
(c-
>contents.su-
>fields
)));
1183 /*@i@
*/ return
(c
); /* not a real copy for conj's
*/
1185 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
()
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
);
2381 ** returns lowest level base of c
: plain type
2384 static
/*@notnull@
*/ /*@only@
*/ ctbase
2385 ctbase_getBaseType
(/*@notnull@
*/ ctbase c
)
2400 return
(ctbase_copy
(c
));
2404 return
(ctbase_getBaseType
(ctype_getCtbaseSafe
(c-
>contents.base
)));
2407 return
(ctbase_getBaseType
(ctype_getCtbaseSafe
(c-
>contents.farray-
>base
)));
2408 case CT_CONJ
: /* base type of A conj branch?
*/
2409 return
(ctbase_getBaseType
(ctype_getCtbaseSafe
(c-
>contents.conj-
>a
)));
2411 return
(ctbase_copy
(c
));
2414 llfatalbug
(message
("ctbase_getBaseType: bad ctbase: %q", ctbase_unparse
(c
)));
2421 ctbase_compare
(ctbase c1
, ctbase c2
, bool strict
)
2425 if
(ctbase_isUndefined
(c1
) || ctbase_isUndefined
(c2
))
2427 llcontbuglit
("ctbase_compare: undefined ctbase");
2444 return
(int_compare
(c1-
>contents.prim
, c2-
>contents.prim
));
2448 return
(typeId_compare
(c1-
>contents.tid
, c2-
>contents.tid
));
2451 case CT_ENUM
: /* for now
, keep like abstract
*/
2454 return
(typeId_compare
(c1-
>contents.tid
, c2-
>contents.tid
));
2456 return
(ctype_compare
(c1-
>contents.base
, c2-
>contents.base
));
2458 INTCOMPARERETURN
(c1-
>contents.farray-
>size
, c2-
>contents.farray-
>size
);
2460 return
(ctype_compare
(c1-
>contents.farray-
>base
,
2461 c2-
>contents.farray-
>base
));
2463 return
(ctype_compare
(c1-
>contents.base
, c2-
>contents.base
));
2466 COMPARERETURN
(ctype_compare
(c1-
>contents.fcn-
>rval
, c2-
>contents.fcn-
>rval
));
2470 return
(uentryList_compareStrict
(c1-
>contents.fcn-
>params
,
2471 c2-
>contents.fcn-
>params
));
2475 return
(uentryList_compareParams
(c1-
>contents.fcn-
>params
,
2476 c2-
>contents.fcn-
>params
));
2480 return
(ctype_compare
(c1-
>contents.base
, c2-
>contents.base
));
2483 /* evs
2000-07-28: this block was missing
! */
2485 int ncmp
= cstring_compare
(c1-
>contents.su-
>name
,
2486 c2-
>contents.su-
>name
);
2489 if
(isFakeTag
(c1-
>contents.su-
>name
)
2490 && isFakeTag (c2->contents.su->name)) {
2491 ; /* If they are both fake struct tags
, don't require match.
*/
2498 DPRINTF
(("Comparing fields: %s / %s",
2499 ctbase_unparse
(c1
),
2500 ctbase_unparse
(c2
)));
2502 return
(uentryList_compareFields
(c1-
>contents.su-
>fields
,
2503 c2-
>contents.su-
>fields
));
2506 COMPARERETURN
(ctype_compare
(c1-
>contents.conj-
>a
,
2507 c2-
>contents.conj-
>a
));
2508 COMPARERETURN
(ctype_compare
(c1-
>contents.conj-
>b
,
2509 c2-
>contents.conj-
>b
));
2510 return
(bool_compare
(c1-
>contents.conj-
>isExplicit
,
2511 c2-
>contents.conj-
>isExplicit
));
2518 ctbase_compareStrict
(/*@notnull@
*/ ctbase c1
, /*@notnull@
*/ ctbase c2
)
2520 return
(ctbase_compare
(c1
, c2
, TRUE));
2523 static bool ctbase_equivStrict
(/*@notnull@
*/ ctbase c1
, /*@notnull@
*/ ctbase c2
)
2525 return
(ctbase_compareStrict
(c1
,c2
) == 0);
2528 static bool ctbase_equiv
(/*@notnull@
*/ ctbase c1
, /*@notnull@
*/ ctbase c2
)
2530 return
(ctbase_compare
(c1
, c2
, FALSE) == 0);
2534 ctbase_isKind
(/*@notnull@
*/ ctbase c
, ctuid kind
)
2542 return
(ctbase_isKind
(ctype_getCtbaseSafe
(c-
>contents.conj-
>a
), kind
) ||
2543 ctbase_isKind
(ctype_getCtbaseSafe
(c-
>contents.conj-
>b
), kind
));
2549 ctbase_isKind2
(/*@notnull@
*/ ctbase c
, ctuid kind1
, ctuid kind2
)
2553 if
(ck
== kind1 || ck
== kind2
)
2557 return
(ctbase_isKind2
(ctype_getCtbaseSafe
(c-
>contents.conj-
>a
), kind1
, kind2
) ||
2558 ctbase_isKind2
(ctype_getCtbaseSafe
(c-
>contents.conj-
>b
), kind1
, kind2
));
2564 ctbase_isAbstract
(/*@notnull@
*/ ctbase c
)
2566 return
(c-
>type
== CT_ABST || c-
>type
== CT_NUMABST
);
2570 ctbase_isNumAbstract
(/*@notnull@
*/ ctbase c
)
2572 return
(c-
>type
== CT_NUMABST
);
2575 static bool ctbase_isUA
(ctbase c
)
2577 return
(ctbase_isDefined
(c
) && (ctuid_isAnyUserType (c->type)));
2581 ctbase_almostEqual
(ctbase c1
, ctbase c2
)
2585 /* undefined types never match
*/
2587 if
(ctbase_isUndefined
(c1
) || ctbase_isUndefined
(c2
))
2593 if
(c1tid
== CT_FIXEDARRAY
&& c2tid == CT_ARRAY)
2595 return
(ctbase_almostEqual
(ctype_getCtbase
(c1-
>contents.farray-
>base
),
2596 ctype_getCtbase
(c2-
>contents.base
)));
2599 if
(c2tid
== CT_FIXEDARRAY
&& c1tid == CT_ARRAY)
2601 return
(ctbase_almostEqual
(ctype_getCtbase
(c1-
>contents.base
),
2602 ctype_getCtbase
(c2-
>contents.farray-
>base
)));
2613 return
(cprim_equal
(c1-
>contents.prim
, c2-
>contents.prim
));
2619 return
(typeId_equal
(c1-
>contents.tid
, c2-
>contents.tid
));
2621 return
(cstring_equal
(c1-
>contents.cenum-
>tag
, c2-
>contents.cenum-
>tag
));
2623 return
(ctype_almostEqual
(c1-
>contents.base
, c2-
>contents.base
));
2625 return
(ctype_almostEqual
(c1-
>contents.farray-
>base
,
2626 c2-
>contents.farray-
>base
));
2628 return
(ctype_almostEqual
(c1-
>contents.base
, c2-
>contents.base
));
2630 return
(ctype_almostEqual
(c1-
>contents.fcn-
>rval
, c2-
>contents.fcn-
>rval
)
2631 && uentryList_matchParams (c1->contents.fcn->params,
2632 c2-
>contents.fcn-
>params
, FALSE, TRUE));
2635 if
(!cstring_isEmpty
(c1-
>contents.su-
>name
))
2637 return
(cstring_equal
(c1-
>contents.su-
>name
, c2-
>contents.su-
>name
));
2641 if
(!cstring_isEmpty
(c2-
>contents.su-
>name
))
2646 llcontbuglit
("ctbase_almostEqual: match fields");
2650 llcontbug
(message
("ctbase_almostEqual: unknown type: %d\n", (int
)c1tid
));
2655 /*drl added July
02, 001
2656 called by ctype_getArraySize
2659 size_t ctbase_getArraySize
(ctbase ctb
)
2661 /*drl
1/25/2002 fixed discovered by Jim Francis
*/
2664 llassert
(ctbase_isDefined
(ctb
) );
2665 r
= ctbase_realType
(ctb
);
2666 llassert
(ctbase_isFixedArray
(r
) );
2668 return
(r-
>contents.farray-
>size
);
2671 bool ctbase_isBigger
(ctbase ct1
, ctbase ct2
)
2673 if
(ct1
!= NULL && ct2 != NULL
2674 && (ct1->type == CT_PRIM && ct2->type == CT_PRIM))
2676 /* Only compare sizes for primitives
*/
2677 cprim cp1
= ct1-
>contents.prim
;
2678 cprim cp2
= ct2-
>contents.prim
;
2679 int nbits1
= cprim_getExpectedBits
(cp1
);
2680 int nbits2
= cprim_getExpectedBits
(cp2
);
2682 if
(nbits1
> nbits2
) {
2694 int ctbase_getSize
(ctbase ct
)
2707 cprim cp
= ct-
>contents.prim
;
2708 int nbits
= cprim_getExpectedBits
(cp
);
2720 /* Malloc returns void
*, but they are bytes. Normal void
* is pointer size.
*/
2721 if
(ctype_isVoid
(ct-
>contents.base
))
2727 return ctype_getSize
(ct-
>contents.base
);