]> andersk Git - splint.git/blame - src/ctype.c
Some work on the files in os2/, removed unnecessary
[splint.git] / src / ctype.c
CommitLineData
616915dd 1/*
2** LCLint - annotation-assisted static program checker
28bf4b0b 3** Copyright (C) 1994-2001 University of Virginia,
616915dd 4** Massachusetts Institute of Technology
5**
6** This program is free software; you can redistribute it and/or modify it
7** under the terms of the GNU General Public License as published by the
8** Free Software Foundation; either version 2 of the License, or (at your
9** option) any later version.
10**
11** This program is distributed in the hope that it will be useful, but
12** WITHOUT ANY WARRANTY; without even the implied warranty of
13** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14** General Public License for more details.
15**
16** The GNU General Public License is available from http://www.gnu.org/ or
17** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18** MA 02111-1307, USA.
19**
20** For information on lclint: lclint-request@cs.virginia.edu
21** To report a bug: lclint-bug@cs.virginia.edu
22** For more information: http://lclint.cs.virginia.edu
23*/
24/*
25** ctype.c
26**
27** This files implements three types: ctentry, cttable and ctype.
28** They should probably be separated soon.
29*/
30
31# include "lclintMacros.nf"
32# include "basic.h"
33# include "structNames.h"
34
35static void ctype_recordConj (ctype p_c);
36
37
38/*
39** ctbase file
40*/
41
42# include "ctbase.i"
43
44/*
45** ctype table
46*/
47
48# include "cttable.i"
49
50static ctype ctype_getConjA (ctype p_c) /*@*/ ;
51static ctype ctype_getConjB (ctype p_c) /*@*/ ;
52
53static bool ctype_isComplex (ctype c)
54{
55 return (ctentry_isComplex (ctype_getCtentry(c)));
56}
57
58static bool ctype_isPlain (ctype c)
59{
60 return (ctentry_isPlain (ctype_getCtentry(c)));
61}
62
63static bool ctype_isBroken (ctype c)
64{
65 /*@+enumint@*/
66 if (c == CTK_DNE || c == CTK_INVALID || c == CTK_UNKNOWN)
67 {
68 /*@-enumint@*/
69 return TRUE;
70 }
71 else
72 {
73 ctentry cte = ctype_getCtentry (c);
74
75 return (ctentry_isBogus (cte));
76 }
77}
78
79ctkind
80ctkind_fromInt (int i)
81{
82 /*@+enumint@*/
83 if (i < CTK_UNKNOWN || i > CTK_COMPLEX)
84 {
85 llcontbug (message ("ctkind_fromInt: out of range: %d", i));
86 return CTK_INVALID;
87 }
88 return (ctkind) i;
89 /*@=enumint@*/
90}
91
92/*
93** ctype functions
94*/
95
96void
97ctype_initTable ()
98{
99 cttable_init ();
100}
101
102void
103ctype_destroyMod ()
104{
105 cttable_reset ();
106}
107
108void
109ctype_loadTable (FILE *f)
110{
28bf4b0b 111 DPRINTF (("Loading cttable!"));
616915dd 112 cttable_load (f);
113}
114
115void
116ctype_dumpTable (FILE *f)
117{
118 DPRINTF (("Dumping cttable!"));
119 cttable_dump (f);
120}
121
122cstring
123ctype_unparseTable ()
124{
125 return (cttable_unparse ());
126}
127
128void
129ctype_printTable ()
130{
131 cttable_print ();
132}
133
134bool
135ctype_isUserBool (ctype ct)
136{
137 if (ctype_isUA (ct))
138 {
139 return (usymtab_isBoolType (ctype_typeId (ct)));
140 }
141
142 return (FALSE);
143}
144
145ctype
146ctype_createUser (typeId u)
147{
148 /* requires: ctype_createUser (u) is never called more than once for any u. */
149
150 ctbase ct = ctbase_createUser (u);
151 return (cttable_addFullSafe (ctentry_makeNew (CTK_PLAIN, ct)));
152}
153
154ctype
155ctype_createAbstract (typeId u)
156{
157 /* requires: ctype_createAbstract (u) is never called more than once for any u. */
158 /* [ tested by cttable_addFullSafe, not really required ] */
159 return (cttable_addFullSafe (ctentry_makeNew (CTK_PLAIN, ctbase_createAbstract (u))));
160}
161
162int
163ctype_count (void)
164{
165 return (cttab.size);
166}
167
168ctype
169ctype_realType (ctype c)
170{
171 ctype r = c;
172
2c88d156 173 if (ctype_isElips (c) || ctype_isMissingParamsMarker (c))
174 {
175 return c;
176 }
177
616915dd 178 if (ctype_isUA (c))
179 {
180 r = uentry_getRealType (usymtab_getTypeEntry (ctype_typeId (c)));
181 }
182
183 if (ctype_isManifestBool (r))
184 {
185 if (context_canAccessBool ())
186 {
187 r = context_boolImplementationType ();
188 }
189 }
190
191 return r;
192}
193
194bool
195ctype_isSimple (ctype c)
196{
197 return (!(ctype_isPointer (c)
198 || ctype_isArray (c)
199 || ctype_isFunction (c)));
200}
201
202ctype
203ctype_forceRealType (ctype c)
204{
205 ctype r = c;
206
207 if (ctype_isUA (c))
208 {
209 r = uentry_getForceRealType (usymtab_getTypeEntry (ctype_typeId (c)));
210 }
211
212 return r;
213}
214
215ctype
216ctype_realishType (ctype c)
217{
218 if (ctype_isUA (c))
219 {
220 if (ctype_isManifestBool (c))
221 {
222 return ctype_bool;
223 }
224 else
225 {
226 ctype r = uentry_getRealType (usymtab_getTypeEntry
227 (ctype_typeId (c)));
228 return (r);
229 }
230 }
231
232 return c;
233}
234
235bool
236ctype_isUA (ctype c)
237{
28bf4b0b 238 return (!ctype_isUnknown (c) && ctbase_isUA (ctype_getCtbase (c)));
616915dd 239}
240
241bool
242ctype_isUser (ctype c)
243{
28bf4b0b 244 return (!ctype_isUnknown (c) && ctbase_isUser (ctype_getCtbase (c)));
616915dd 245}
246
247bool
248ctype_isAbstract (ctype c)
249{
28bf4b0b 250 return (!ctype_isUnknown (c)
251 && ((ctype_isPlain (c) && ctbase_isAbstract (ctype_getCtbaseSafe (c))) ||
252 (ctype_isConj (c) &&
253 (ctype_isAbstract (ctype_getConjA (c))
254 || ctype_isAbstract (ctype_getConjB (c))))));
255}
256
257bool
258ctype_isImmutableAbstract (ctype t)
259{
260 return (ctype_isAbstract (t) && !ctype_isMutable (t));
616915dd 261}
262
263bool
264ctype_isRealAbstract (ctype c)
265{
266 return (ctype_isAbstract (ctype_realType (c)) ||
267 (ctype_isConj (c) &&
268 (ctype_isRealAbstract (ctype_getConjA (c)) ||
269 ctype_isRealAbstract (ctype_getConjB (c)))));
270}
271
272/*
273** primitive creators
274*/
275
276/*
277** createPrim not necessary --- subsumed by ctype_int, etc.
278*/
279
280/*
281** ctbase_unknown --- removed argument
282*/
283
284/*
285** derived types:
286** requires: if DerivedType (T) exists in cttable, then T->derivedType is it.
287*/
288
289ctype
290ctype_makePointer (ctype c)
291{
292 if (c == ctype_char)
293 {
294 return ctype_string;
295 }
296 else if (c == ctype_void)
297 {
298 return ctype_voidPointer;
299 }
300 else
301 {
302 ctentry cte = ctype_getCtentry (c);
303 ctype clp = ctentry_getPtr (cte);
304
305 if /*@+enumint@*/ (clp == CTK_DNE) /*@=enumint@*/
306 {
307 ctype cnew = cttable_addDerived (CTK_PTR, ctbase_makePointer (c), c);
308 ctentry_setPtr (cte, cnew);
28bf4b0b 309 return (cnew);
616915dd 310 }
311 else
312 {
28bf4b0b 313 return clp;
616915dd 314 }
315 }
316}
317
318ctype ctype_makeFixedArray (ctype c, long size)
319{
320 return (cttable_addDerived (CTK_ARRAY, ctbase_makeFixedArray (c, size), c));
321}
322
323ctype
324ctype_makeArray (ctype c)
325{
326 ctentry cte = ctype_getCtentry (c);
327 ctype clp = ctentry_getArray (cte);
328
329 if /*@+enumint@*/ (clp == CTK_DNE) /*@=enumint@*/
330 {
331 ctype cnew = cttable_addDerived (CTK_ARRAY, ctbase_makeArray (c), c);
332 ctentry_setArray (cte, cnew);
333 return (cnew);
334 }
335 else
336 return clp;
337}
338
339/*
340** requires c is a pointer of array
341*/
342
343ctype
344ctype_baseArrayPtr (ctype c)
345{
346 ctentry cte = ctype_getCtentry (ctype_realType (c));
347
348 if (ctype_isConj (c))
349 {
350 if (ctype_isAP (ctype_getConjA (c)))
351 {
352 if (ctype_isAP (ctype_getConjB (c)))
353 {
354 return (ctype_makeConj (ctype_baseArrayPtr (ctype_getConjA (c)),
355 ctype_baseArrayPtr (ctype_getConjB (c))));
356 }
357 else
358 {
359 return (ctype_baseArrayPtr (ctype_getConjA (c)));
360 }
361 }
362 else
363 {
364 return (ctype_baseArrayPtr (ctype_getConjB (c)));
365 }
366 }
367 else if (ctype_isInt (c)) /* could be NULL */
368 {
369 return ctype_unknown;
370 }
371 else
372 {
373 ctype clp = ctentry_getBase (cte);
374
375 if (ctype_isBroken (clp))
376 {
377 llbuglit ("ctype_baseArrayPtr: bogus ctype");
378 }
379
380 return clp;
381 }
382}
383
384ctype
28bf4b0b 385ctype_getReturnType (ctype c)
616915dd 386{
28bf4b0b 387 if (ctype_isUnknown (c))
388 {
389 return ctype_unknown;
390 }
391
616915dd 392 return (ctbase_baseFunction (ctype_getCtbaseSafe (c)));
393}
394
395/*
396** must be a shared pointer
397*/
398
399/*@observer@*/ uentryList
400ctype_argsFunction (ctype c)
401{
28bf4b0b 402 if (ctype_isUnknown (c))
403 {
404 return uentryList_undefined;
405 }
406
616915dd 407 return (ctbase_argsFunction (ctype_getCtbaseSafe (c)));
408}
409
410/*
411** Returns type with base type p and compound types from c.
412**
413** i.e., c = char *[]; p = int
414** => int *[]
415*/
416
417ctype
418ctype_newBase (ctype c, ctype p)
419{
420 return (ctbase_newBase (c, p));
421}
422
423bool
424ctype_sameAltTypes (ctype c1, ctype c2)
425{
426 ctype c1a, c2a;
427 ctype c1b, c2b;
428
429 llassert (ctype_isConj (c1) && ctype_isConj (c2));
430
431 c1a = ctype_getConjA (c1);
432 c2a = ctype_getConjA (c2);
433
434 c1b = ctype_getConjB (c1);
435 c2b = ctype_getConjB (c2);
436
437 if (ctype_compare (c1a, c2a) == 0)
438 {
439 if (ctype_compare (c1b, c2b) == 0)
440 {
441 return TRUE;
442 }
443 else
444 {
445 if (ctype_isConj (c1b) && ctype_isConj (c2b))
446 {
447 return ctype_sameAltTypes (c1b, c2b);
448 }
449 else
450 {
451 return FALSE;
452 }
453 }
454 }
455 else
456 {
457 if (ctype_compare (c1a, c2b) == 0)
458 {
459 if (ctype_compare (c1b, c2a) == 0)
460 {
461 return TRUE;
462 }
463 else
464 {
465 if (ctype_isConj (c1b) && ctype_isConj (c2a))
466 {
467 return ctype_sameAltTypes (c1b, c2a);
468 }
469 else
470 {
471 return FALSE;
472 }
473 }
474 }
475 else
476 {
477 return FALSE;
478 }
479 }
480}
481
482int
483ctype_compare (ctype c1, ctype c2)
484{
485 ctentry ce1;
486 ctentry ce2;
487
28bf4b0b 488 if (ctype_isUnknown (c1))
489 {
490 if (ctype_isUnknown (c2))
491 {
492 return 0;
493 }
494 else
495 {
496 return 1;
497 }
498 }
499
500 if (ctype_isUnknown (c2))
501 {
502 return -1;
503 }
504
616915dd 505 /* Can't get entries for special ctypes (elips marker) */
506
507 if (ctype_isElips (c1) || ctype_isElips (c2)
508 || ctype_isMissingParamsMarker (c1) || ctype_isMissingParamsMarker (c2)) {
509 return int_compare (c1, c2);
510 }
511
512 ce1 = ctype_getCtentry (c1);
513 ce2 = ctype_getCtentry (c2);
514
515 if (ctentry_isComplex (ce1))
516 {
517 if (ctentry_isComplex (ce2))
518 {
519 return (ctbase_compare (ctype_getCtbase (c1),
520 ctype_getCtbase (c2), FALSE));
521 }
522 else
523 {
524 return 1;
525 }
526 }
527 else if (ctentry_isComplex (ce2))
528 {
529 return -1;
530 }
531 else
532 {
533 return (int_compare (c1, c2));
534 }
535}
536
537/*
538** complex types
539*/
540
541/*
542** makeFunction: pointer to function returning base
543*/
544
545ctype
546ctype_makeParamsFunction (ctype base, /*@only@*/ uentryList p)
547{
548 uentryList_fixImpParams (p);
549 return (ctype_makeFunction (base, p));
550}
551
552ctype
553ctype_makeNFParamsFunction (ctype base, /*@only@*/ uentryList p)
554{
555 uentryList_fixImpParams (p);
556 return (ctbase_makeNFFunction (base, p));
557}
558
559ctype
560ctype_makeFunction (ctype base, /*@only@*/ uentryList p)
561{
562 ctype ret;
563 ret = ctbase_makeFunction (base, p);
564 return (ret);
565}
566
567ctype ctype_expectFunction (ctype c)
568{
569 /* handle parenthesized declarations */
570
571 if (!ctype_isAP (c))
572 {
573 c = ctype_makePointer (c);
574 }
575
576 return (cttable_addComplex (ctbase_expectFunction (c)));
577}
578
579/*
580** makeRealFunction: function returning base
581*/
582
28bf4b0b 583ctype ctype_makeRawFunction (ctype base, uentryList p)
616915dd 584{
28bf4b0b 585 return (cttable_addComplex (ctbase_makeLiveFunction (base, p)));
616915dd 586}
587
588/*
589** plain predicates
590*/
591
592/***
593**** this is very poorly defined
594****
595**** need to unify function/function pointer meaning
596***/
597
598bool
599ctype_isFunction (ctype c)
600{
28bf4b0b 601 if (ctype_isKnown (c) && ctype_isDefined (c))
602 {
603 return (ctbase_isFunction (ctype_getCtbase (c)));
604 }
605 else
606 {
607 return FALSE;
608 }
616915dd 609}
610
611bool
612ctype_isExpFcn (ctype c)
613{
28bf4b0b 614 return (ctype_isKnown (c) && ctbase_isExpFcn (ctype_getCtbase (c)));
616915dd 615}
616
617bool
618ctype_isVoid (ctype c)
619{
620 return (c == CTX_VOID);
621}
622
623bool
624ctype_isArbitraryIntegral (ctype c)
625{
626 ctype cr = ctype_realType (c);
627
628 return (cr == ctype_anyintegral || cr == ctype_unsignedintegral
629 || cr == ctype_signedintegral);
630}
631
632bool
633ctype_isUnsignedIntegral (ctype c)
634{
635 ctype cr = ctype_realType (c);
636
637 return (cr == ctype_unsignedintegral);
638}
639
640bool
641ctype_isSignedIntegral (ctype c)
642{
643 ctype cr = ctype_realType (c);
644
645 return (cr == ctype_signedintegral);
646}
647
648bool
649ctype_isInt (ctype c)
650{
651 cprim cp = ctype_toCprim (c);
652
653 return (c == ctype_unknown || cprim_isAnyInt (cp)
654 || (cprim_isAnyChar (cp) && context_msgCharInt ())
655 || (c == ctype_bool && context_msgBoolInt ())
656 || (ctype_isEnum (c) && context_msgEnumInt ()));
657}
658
659bool
660ctype_isRegularInt (ctype c)
661{
662 cprim cp = ctype_toCprim (c);
663
664 return (c == ctype_unknown
665 || cprim_closeEnough (cprim_int, cp)
666 || (cprim_isAnyChar (cp) && context_msgCharInt ())
667 || (c == ctype_bool && context_msgBoolInt ())
668 || (ctype_isEnum (c) && context_msgEnumInt ()));
669}
670
671bool
672ctype_isString (ctype c)
673{
674 return (c == ctype_string
675 || (ctype_isPointer (c)
676 && ctype_isChar (ctype_baseArrayPtr (c))));
677}
678
679bool
680ctype_isChar (ctype c)
681{
682 return ((c == ctype_unknown) || (cprim_isAnyChar (ctype_toCprim (c)))
683 || (context_getFlag (FLG_CHARINT) && ctype_isInt (c)));
684}
685
686bool
687ctype_isUnsignedChar (ctype c)
688{
689 return ((c == ctype_unknown) || (cprim_isUnsignedChar (ctype_toCprim (c))));
690}
691
692bool
693ctype_isSignedChar (ctype c)
694{
695 return ((c == ctype_unknown) || (cprim_isSignedChar (ctype_toCprim (c))));
696}
697
698/*
699** Returns true if c matches the name -booltype <bool>
700*/
701
702bool
703ctype_isManifestBool (ctype c)
704{
705 /*
706 ** Changed the meaning of ctype_isBool - evs 2000-07-24
707 ** The old meaning was very convoluted!
708 **
709 ** c is a bool if:
710 ** c == CTX_BOOL - its a direct bool
711 ** c is a user/abstract type matching the bool name
712 ** (should never occur?)
713 */
714
715 if (ctype_isDirectBool (c)) {
716 return TRUE;
717 } else if (ctype_isUA (c)) {
718 return ctype_isUserBool (c);
719 } else {
720 return FALSE;
721 }
722}
723
724bool
725ctype_isBool (ctype c)
726{
727 /*
728 ** Changed the meaning of ctype_isBool - evs 2000-07-24
729 ** The old meaning was very convoluted!
730 **
731 ** c is a bool if:
732 ** its a manifest bool
733 ** +boolint and ctype_isInt (c)
734 */
735
736 if (ctype_isManifestBool (c)) {
737 return TRUE;
738 } else if (context_msgBoolInt ()) {
739 return ctype_isInt (c);
740 } else {
741 return FALSE;
742 }
743
744# if 0
745 if (context_getFlag (FLG_ABSTRACTBOOL))
746 {
747 if (typeId_isInvalid (boolType))
748 {
749 boolType = usymtab_getTypeId (context_getBoolName ());
750 }
751
752 if (context_hasAccess (boolType))
753 {
754 return (((c == CTX_UNKNOWN) || (c == CTX_BOOL)
755 || (context_msgBoolInt ()
756 && (c == CTX_INT
757 || (c == CTX_CHAR && context_msgCharInt ()))))
758 || ctype_isInt (c));
759 }
760 }
761
762 return ((c == CTX_UNKNOWN) || (c == CTX_BOOL)
763 || (context_msgBoolInt ()
764 && (c == CTX_INT || (c == CTX_CHAR && context_msgCharInt ()))));
765# endif
766}
767
768bool
769ctype_isDirectBool (ctype c)
770{
771 return (c == CTX_BOOL);
772}
773
774bool
775ctype_isReal (ctype c)
776{
777 return (cprim_isAnyReal (ctype_toCprim (c)));
778}
779
780bool
781ctype_isFloat (ctype c)
782{
783 return (c == ctype_float);
784}
785
786bool
787ctype_isDouble (ctype c)
788{
789 return (c == ctype_double || c == ctype_ldouble);
790}
791
792bool
793ctype_isSigned (ctype c)
794{
795 return (!ctype_isUnsigned (c));
796}
797
798bool
799ctype_isNumeric (ctype c)
800{
801 return (ctype_isInt (c) || ctype_isReal (c) || ctype_isEnum (c));
802}
803
804
805/*
806** real predicates
807**
808** work on actual type in current context
809*/
810
811bool
812ctype_isRealNumeric (ctype c)
813{
814 if (ctype_isPlain (c))
815 return (ctype_isNumeric (ctype_realType (c)));
816 if (ctype_isConj (c))
817 return (ctype_isRealNumeric (ctype_getConjA (c)) ||
818 ctype_isRealNumeric (ctype_getConjB (c)));
819 else
820 return FALSE;
821}
822
823bool
824ctype_isRealInt (ctype c)
825{
826 if (ctype_isPlain (c))
827 return (ctype_isInt (ctype_realType (c)));
828 else if (ctype_isConj (c))
829 return (ctype_isRealInt (ctype_getConjA (c)) ||
830 ctype_isRealInt (ctype_getConjB (c)));
831 else
832 {
833 if (ctype_isEnum (c) && context_msgEnumInt ()) return TRUE;
834 return FALSE;
835 }
836}
837
838bool
839ctype_isRealVoid (ctype c)
840{
841 if (ctype_isPlain (c))
842 {
843 return (ctype_isVoid (ctype_realType (c)));
844 }
845 else if (ctype_isConj (c))
846 {
847 return (ctype_isRealVoid (ctype_getConjA (c)) ||
848 ctype_isRealVoid (ctype_getConjB (c)));
849 }
850 else
851 {
852 return FALSE;
853 }
854}
855
856bool
857ctype_isRealBool (ctype c)
858{
859 if (ctype_isPlain (c))
860 {
861 return (ctype_isBool (ctype_realishType (c)));
862 }
863 else if (ctype_isConj (c))
864 {
865 return (ctype_isRealBool (ctype_getConjA (c)) ||
866 ctype_isRealBool (ctype_getConjB (c)));
867 }
868 else
869 {
870 return FALSE;
871 }
872}
873
874bool
875ctype_isRealPointer (ctype c)
876{
877 if (ctype_isConj (c))
878 return (ctype_isRealPointer (ctype_getConjA (c)) ||
879 ctype_isRealPointer (ctype_getConjB (c)));
880 return (ctype_isPointer (ctype_realType (c)));
881}
882
883bool
884ctype_isRealSU (ctype c)
885{
886 if (ctype_isConj (c))
887 {
888 return (ctype_isRealSU (ctype_getConjA (c)) ||
889 ctype_isRealSU (ctype_getConjB (c)));
890 }
28bf4b0b 891
892 DPRINTF (("Real su: %s / %s", ctype_unparse (c), ctype_unparse (ctype_realType (c))));
616915dd 893 return (ctype_isStructorUnion (ctype_realType (c)));
894}
895
896bool
897ctype_isRealArray (ctype c)
898{
899 if (ctype_isConj (c))
900 return (ctype_isRealArray (ctype_getConjA (c)) ||
901 ctype_isRealArray (ctype_getConjB (c)));
902 return (ctype_isArray (ctype_realType (c)));
903}
904
905bool
906ctype_isRealAP (ctype c)
907{
908 if (ctype_isConj (c))
909 return (ctype_isRealAP (ctype_getConjA (c)) ||
910 ctype_isRealAP (ctype_getConjB (c)));
911 return (ctype_isAP (ctype_realType (c)));
912}
913
914bool
915ctype_isRealFunction (ctype c)
916{
917 if (ctype_isConj (c))
918 return (ctype_isRealFunction (ctype_getConjA (c)) ||
919 ctype_isRealFunction (ctype_getConjB (c)));
920 return (ctype_isFunction (ctype_realType (c)));
921}
922
923bool
924ctype_isDirectInt (ctype c)
925{
926 return (c == CTX_INT || c == CTX_UINT || c == CTX_SINT || c == CTX_ULINT || c == CTX_USINT);
927}
928
929/*
930** forceful predicates
931**
932** take *ctype; if its a conjunct, and there is a match replace with match only.
933** if both match, still conjunct
934*/
935
936static bool
937 ctype_isForcePred (ctype * c, bool (pred) (ctype))
938{
939 if (ctype_isConj (*c))
940 {
941 ctype cbr = ctype_getConjA (*c);
942
943 if ((*pred) (cbr))
944 {
945 if ((*pred) (ctype_getConjB (*c)))
946 {
947 ;
948 }
949 else
950 {
951 *c = cbr;
952 }
953
954 return TRUE;
955 }
956 else
957 {
958 if ((*pred) (cbr = ctype_getConjB (*c)))
959 {
960 *c = cbr;
961 return TRUE;
962 }
963 }
964 }
965
966 return ((*pred) (*c));
967}
968
969bool
970ctype_isForceRealNumeric (ctype * c)
971{
972 return (ctype_isForcePred (c, ctype_isRealNumeric));
973}
974
975bool
976ctype_isForceRealInt (ctype * c)
977{
978 return (ctype_isForcePred (c, ctype_isRealInt));
979}
980
981bool
982ctype_isForceRealBool (ctype * c)
983{
984 return (ctype_isForcePred (c, ctype_isRealBool));
985}
986
987/*
988** conjuncts
989**
990** save int/char, int/bool, other random conjuncts
991*/
992
993static ctype
994ctype_makeConjAux (ctype c1, ctype c2, bool isExplicit)
995{
996 if (ctype_isBogus (c1) || ctype_isUndefined (c1))
997 {
998 return c2;
999 }
1000 else if (ctype_isBogus (c2) || ctype_isUndefined (c2))
1001 {
1002 return c1;
1003 }
1004 else
1005 {
1006 if (isExplicit)
1007 {
1008 return (ctype_makeExplicitConj (c1, c2));
1009 }
1010 else
1011 {
1012 return (ctype_makeConj (c1, c2));
1013 }
1014 }
1015}
1016
1017ctype
1018ctype_makeExplicitConj (ctype c1, ctype c2)
1019{
1020 if (ctype_isFunction (c1) && !ctype_isFunction (c2))
1021 {
28bf4b0b 1022 ctype ret = ctype_makeExplicitConj (ctype_getReturnType (c1), c2);
616915dd 1023
1024 return ctype_makeFunction (ret, uentryList_copy (ctype_getParams (c1)));
1025 }
1026 else if (ctype_isFunction (c2) && !ctype_isFunction (c1))
1027 {
28bf4b0b 1028 ctype ret = ctype_makeExplicitConj (c1, ctype_getReturnType (c2));
616915dd 1029
1030 return ctype_makeFunction (ret, uentryList_copy (ctype_getParams (c2)));
1031 }
1032 else
1033 {
1034 return (cttable_addComplex (ctbase_makeConj (c1, c2, TRUE)));
1035 }
1036}
1037
1038static ctype ic = ctype_unknown; /* int | char */
1039static ctype ib = ctype_unknown; /* int | bool */
1040static ctype ifl = ctype_unknown; /* int | float */
1041static ctype ibf = ctype_unknown; /* int | bool | float */
1042static ctype ibc = ctype_unknown; /* int | bool | char */
1043static ctype iv = ctype_unknown; /* int | void * */
1044static ctype ivf = ctype_unknown; /* int | void * | float */
1045static ctype ivb = ctype_unknown; /* int | void * | bool */
1046static ctype ivbf = ctype_unknown; /* int | void * | bool | float */
1047static ctype cuc = ctype_unknown; /* char | unsigned char */
1048
1049static void
1050ctype_recordConj (ctype c)
1051{
1052 ctype c1, c2;
1053
1054 llassert (ctype_isConj (c));
1055
1056 c1 = ctype_getConjA (c);
1057 c2 = ctype_getConjB (c);
1058
1059 /* No, can't swap!
1060 if (c2 == ctype_int && c1 != ctype_int)
1061 {
1062 ctype tmp;
1063
1064 tmp = c1;
1065 c1 = c2;
1066 c2 = tmp;
1067 }
1068 */
1069
1070 if (c1 == ctype_int)
1071 {
1072 if (c2 == ctype_char)
1073 {
1074 llassert (ic == ctype_unknown);
1075 ic = c;
1076 }
1077 else if (c2 == ctype_bool)
1078 {
1079 llassert (ib == ctype_unknown);
1080 ib = c;
1081 }
1082 else if (c2 == ctype_float)
1083 {
1084 llassert (ifl == ctype_unknown);
1085 ifl = c;
1086 }
1087 else if (c2 == CTP_VOID)
1088 {
1089 llassert (iv == ctype_unknown);
1090 iv = c;
1091 }
1092 else
1093 {
1094 /* not special */
1095 }
1096 }
1097 else if (c1 == ib && ib != ctype_unknown)
1098 {
1099 if (c2 == ctype_float)
1100 {
1101 llassert (ibf == ctype_unknown);
1102 ibf = c;
1103 }
1104 else if (c2 == ctype_char)
1105 {
1106 llassert (ibc == ctype_unknown);
1107 ibc = c;
1108 }
1109 else
1110 {
1111 /* not special */
1112 }
1113 }
1114 else if (c1 == iv)
1115 {
1116 if (c2 == ctype_bool)
1117 {
1118 llassert (ivb == ctype_unknown);
1119 ivb = c;
1120 }
1121 else if (c2 == ctype_float)
1122 {
1123 llassert (ivf == ctype_unknown);
1124 ivf = c;
1125 }
1126 else
1127 {
1128 /* not special */
1129 }
1130 }
1131 else if (c1 == ivf)
1132 {
1133 if (c2 == ctype_bool)
1134 {
1135 llassert (ivbf == ctype_unknown);
1136 ivbf = c;
1137 }
1138 }
1139 else if (c1 == ivb)
1140 {
1141 if (c2 == ctype_float)
1142 {
1143 llassert (ivbf == ctype_unknown);
1144 ivbf = c;
1145 }
1146 }
1147 else if (c1 == ctype_char)
1148 {
1149 if (c2 == ctype_uchar)
1150 {
1151 llassert (cuc == ctype_unknown);
1152
1153 cuc = c;
1154 }
1155 }
1156 else
1157 {
1158 /* not special */
1159 }
1160}
1161
1162ctype
1163ctype_makeConj (ctype c1, ctype c2)
1164{
1165 /* no: can have unsigned long @alt long@: llassert (c1 != c2); */
1166
1167 DPRINTF (("Make conj: %s / %s", ctype_unparse (c1), ctype_unparse (c2)));
1168
28bf4b0b 1169 if (ctype_isUnknown (c1))
616915dd 1170 {
28bf4b0b 1171 return c2;
1172 }
1173 else if (ctype_isUnknown (c2))
1174 {
1175 return c1;
1176 }
1177 else if (ctype_isFunction (c1) && !ctype_isFunction (c2))
1178 {
1179 ctype ret = ctype_makeConj (ctype_getReturnType (c1), c2);
616915dd 1180 return ctype_makeFunction (ret, uentryList_copy (ctype_getParams (c1)));
1181 }
1182 else if (ctype_isFunction (c2) && !ctype_isFunction (c1))
1183 {
28bf4b0b 1184 ctype ret = ctype_makeConj (c1, ctype_getReturnType (c2));
616915dd 1185 return ctype_makeFunction (ret, uentryList_copy (ctype_getParams (c2)));
1186 }
1187 else
1188 {
1189 if (ctype_isManifestBool (c1))
1190 {
1191 c1 = ctype_bool;
1192 }
1193
1194 if (ctype_isManifestBool (c2))
1195 {
1196 c2 = ctype_bool;
1197 }
1198
1199 if (ctbase_isVoidPointer (ctype_getCtbaseSafe (c1)))
1200 {
1201 c1 = ctype_voidPointer;
1202 }
1203
1204 if (ctbase_isVoidPointer (ctype_getCtbaseSafe (c2)))
1205 {
1206 c2 = ctype_voidPointer;
1207 }
1208
1209 /*
1210 ** Ouch, can't do this. unsigned, etc. modifiers might
1211 ** apply to wrong type!
1212 **
1213 ** if (c2 == ctype_int && c1 != ctype_int)
1214 ** {
1215 ** ctype tmp;
1216 **
1217 ** tmp = c1;
1218 ** c1 = c2;
1219 ** c2 = tmp;
1220 ** }
1221 **
1222 */
1223
1224 if (c1 == ctype_int)
1225 {
1226 if (c2 == ctype_char)
1227 {
1228 if (ic == ctype_unknown)
1229 {
1230 ic = cttable_addComplex (ctbase_makeConj (ctype_int, ctype_char, FALSE));
1231 }
1232
1233 return ic;
1234 }
1235 else if (c2 == ctype_bool)
1236 {
1237 if (ib == ctype_unknown)
1238 {
1239 ib = cttable_addComplex
1240 (ctbase_makeConj (ctype_int, ctype_bool, FALSE));
1241 }
1242
1243 return ib;
1244 }
1245 else if (c2 == ctype_float)
1246 {
1247 if (ifl == ctype_unknown)
1248 {
1249 ifl = cttable_addComplex (ctbase_makeConj (ctype_int, ctype_float, FALSE));
1250 }
1251
1252 return ifl;
1253 }
1254 else
1255 {
1256 if (c2 == ctype_voidPointer)
1257 {
1258 if (iv == ctype_unknown)
1259 {
1260 iv = cttable_addComplex
1261 (ctbase_makeConj (ctype_int,
1262 ctype_voidPointer,
1263 FALSE));
1264 }
1265
1266 return iv;
1267 }
1268 }
1269 }
1270 else if (c1 == ib && ib != ctype_unknown)
1271 {
1272 if (c2 == ctype_float)
1273 {
1274 if (ibf == ctype_unknown)
1275 {
1276 ibf = cttable_addComplex (ctbase_makeConj (ib, ctype_float, FALSE));
1277 }
1278
1279 return ibf;
1280 }
1281 else if (c2 == ctype_char)
1282 {
1283 if (ibc == ctype_unknown)
1284 {
1285 ibc = cttable_addComplex (ctbase_makeConj (ib, ctype_char, FALSE));
1286 }
1287
1288 return ibc;
1289 }
1290 else
1291 {
1292 ;
1293 }
1294 }
1295 else if (c1 == iv)
1296 {
1297 if (c2 == ctype_bool)
1298 {
1299 if (ivb == ctype_unknown)
1300 {
1301 ivb = cttable_addComplex (ctbase_makeConj (c1, c2, FALSE));
1302 }
1303
1304 return ivb;
1305 }
1306 else if (c2 == ctype_float)
1307 {
1308 if (ivf == ctype_unknown)
1309 {
1310 ivf = cttable_addComplex (ctbase_makeConj (c1, c2, FALSE));
1311 }
1312
1313 return ivf;
1314 }
1315 else
1316 {
1317 ;
1318 }
1319 }
1320 else if (c1 == ivf)
1321 {
1322 if (c2 == ctype_bool)
1323 {
1324 if (ivbf == ctype_unknown)
1325 {
1326 ivbf = cttable_addComplex (ctbase_makeConj (c1, c2, FALSE));
1327 }
1328
1329 return ivbf;
1330 }
1331 }
1332 else if (c1 == ivb)
1333 {
1334 if (c2 == ctype_float)
1335 {
1336 if (ivbf == ctype_unknown)
1337 {
1338 ivbf = cttable_addComplex (ctbase_makeConj (c1, c2, FALSE));
1339 }
1340
1341 return ivbf;
1342 }
1343 }
1344 else if (c1 == ctype_char)
1345 {
1346 if (c2 == ctype_uchar)
1347 {
1348 if (cuc == ctype_unknown)
1349 {
1350 cuc = cttable_addComplex (ctbase_makeConj (c1, c2, FALSE));
1351 }
1352
1353 return cuc;
1354 }
1355 }
1356 else
1357 {
1358 ;
1359 }
1360
1361
1362 return (cttable_addComplex (ctbase_makeConj (c1, c2, FALSE)));
1363 }
1364}
1365
1366
1367bool
1368ctype_isConj (ctype c)
1369{
1370 return (ctype_isComplex (c) && ctbase_isConj (ctype_getCtbase (c)));
1371}
1372
1373static ctype
1374ctype_getConjA (ctype c)
1375{
1376 if (!ctype_isConj (c))
1377 llbuglit ("ctype_getConjA: not a conj");
1378 return (ctbase_getConjA (ctype_getCtbaseSafe (c)));
1379}
1380
1381static ctype
1382ctype_getConjB (ctype c)
1383{
1384 if (!ctype_isConj (c))
1385 llbuglit ("ctype_getConjB: not a conj");
1386 return (ctbase_getConjB (ctype_getCtbaseSafe (c)));
1387}
1388
1389static bool
1390ctype_isExplicitConj (ctype c)
1391{
1392 return (ctype_isConj (c) && ctbase_isExplicitConj (ctype_getCtbaseSafe (c)));
1393}
1394
1395/** << need to fix resolveConj >> **/
1396
1397/*
1398** structs and unions
1399*/
1400
1401ctype
1402ctype_createStruct (/*@only@*/ cstring n, /*@only@*/ uentryList f)
1403{
1404 ctype ct;
1405
1406 DPRINTF (("Creating a struct: %s / %s",
1407 n, uentryList_unparse (f)));
1408
1409 ct = cttable_addComplex (ctbase_createStruct (n, f));
1410 DPRINTF (("ct: %s", ctype_unparse (ct)));
1411 return (ct);
1412}
1413
1414uentryList
1415ctype_getFields (ctype c)
1416{
1417 return (ctbase_getuentryList (ctype_getCtbaseSafe (c)));
1418}
1419
1420ctype
1421ctype_createUnion (/*@only@*/ cstring n, /*@only@*/ uentryList f)
1422{
1423 ctype ret;
1424
1425 ret = cttable_addComplex (ctbase_createUnion (n, f));
1426 return ret;
1427}
1428
1429/*
1430** matching
1431**
1432** if ctype's are same, definite match.
1433** else, need to call ctbase_match.
1434**
1435** if necessary context can memoize matches
1436*/
1437
1438static bool
1439 quickMatch (ctype c1, ctype c2)
1440{
1441 if (c1 == c2)
1442 return TRUE;
1443
1444 return FALSE;
1445}
1446
1447bool
1448ctype_genMatch (ctype c1, ctype c2, bool force, bool arg, bool def, bool deep)
1449{
1450 bool match;
1451
1452 DPRINTF (("Gen match: %s / %s arg: %s", ctype_unparse (c1), ctype_unparse (c2), bool_unparse (arg)));
1453
1454 if (quickMatch (c1, c2))
1455 {
1456 return TRUE;
1457 }
1458
1459 if (ctype_isElips (c1) || ctype_isElips (c2))
1460 {
1461 return FALSE;
1462 }
1463 else
1464 {
1465 match = ctbase_genMatch (ctype_getCtbase (c1), ctype_getCtbase (c2), force, arg, def, deep);
1466 return (match);
1467 }
1468}
1469
1470bool
1471ctype_sameName (ctype c1, ctype c2)
1472{
1473 if (quickMatch (c1, c2))
1474 return TRUE;
1475 else
1476 return (cstring_equal (ctype_unparse (c1), ctype_unparse (c2)));
1477}
1478
1479bool
1480ctype_almostEqual (ctype c1, ctype c2)
1481{
1482 if (ctype_equal (c1, c2))
1483 {
1484 return TRUE;
1485 }
1486 else
1487 {
28bf4b0b 1488 if (ctype_isUnknown (c1))
1489 {
1490 return ctype_isUnknown (c2);
1491 }
1492 else if (ctype_isUnknown (c2))
1493 {
1494 return FALSE;
1495 }
1496 else
1497 {
1498 return (ctbase_almostEqual (ctype_getCtbase (c1), ctype_getCtbase (c2)));
1499 }
616915dd 1500 }
1501}
1502
1503bool
1504ctype_matchDef (ctype c1, ctype c2)
1505{
1506 DPRINTF (("Match def: %s / %s", ctype_unparse (c1), ctype_unparse (c2)));
1507
1508 if (quickMatch (c1, c2))
1509 return TRUE;
1510
1511 if (ctype_isElips (c1))
1512 return (ctype_isElips (c2) || ctype_isUnknown (c2));
1513
1514 if (ctype_isElips (c2))
28bf4b0b 1515 {
1516 return (ctype_isUnknown (c2));
1517 }
616915dd 1518 else
1519 {
1520 bool oldrelax = context_getFlag (FLG_RELAXQUALS);
1521 bool res;
1522
1523 context_setFlagTemp (FLG_RELAXQUALS, FALSE);
1524 res = ctbase_matchDef (ctype_getCtbase (c1), ctype_getCtbase (c2));
1525 context_setFlagTemp (FLG_RELAXQUALS, oldrelax);
1526 return res;
1527 }
1528}
1529
1530bool ctype_match (ctype c1, ctype c2)
1531{
1532 if (quickMatch (c1, c2))
1533 return TRUE;
1534
1535 if (ctype_isElips (c1))
1536 return (ctype_isElips (c2) || ctype_isUnknown (c2));
1537
1538 if (ctype_isElips (c2))
1539 return (ctype_isUnknown (c2));
1540
1541 return (ctbase_match (ctype_getCtbase (c1), ctype_getCtbase (c2)));
1542}
1543
1544bool
1545ctype_forceMatch (ctype c1, ctype c2)
1546{
1547 if (quickMatch (c1, c2))
1548 return TRUE;
1549
1550 if (ctype_isElips (c1))
1551 return (ctype_isElips (c2));
1552
1553 if (ctype_isElips (c2))
1554 return FALSE;
1555
1556 /*@-modobserver@*/
1557 /* The call forceMatch may modify the observer params, but, we don't care. */
1558 return (ctbase_forceMatch (ctype_getCtbase (c1), ctype_getCtbase (c2)));
1559 /*@=modobserver@*/
1560}
1561
1562bool
1563ctype_matchArg (ctype c1, ctype c2)
1564{
1565 if (quickMatch (c1, c2))
1566 {
1567 return TRUE;
1568 }
1569 else
1570 {
1571 return (ctbase_matchArg (ctype_getCtbase (c1), ctype_getCtbase (c2)));
1572 }
1573}
1574
1575/*
1576** simple ctype_is operations.
1577** DO NOT use real type of c, only direct type.
1578*/
1579
1580/*
1581** ctype_isVoidPointer
1582**
1583** void *
1584*/
1585
1586bool
1587ctype_isVoidPointer (ctype c)
1588{
1589 if (ctype_isComplex (c))
1590 {
1591 return ctbase_isVoidPointer (ctype_getCtbaseSafe (c));
1592 }
1593 if (ctype_isConj (c))
1594 {
1595 return (ctype_isVoidPointer (ctype_getConjA (c)) ||
1596 ctype_isVoidPointer (ctype_getConjB (c)));
1597 }
1598 else
1599 {
1600 return (c == ctype_voidPointer
1601 || (ctype_isRealPointer (c)
1602 && ctype_isVoid (ctype_baseArrayPtr (c))));
1603 }
1604}
1605
1606/*
1607** ctype_isPointer
1608**
1609** true for C and LCL pointers
1610*/
1611
1612bool
1613ctype_isPointer (ctype c)
1614{
1615 if (ctype_isElips (c)) return FALSE;
1616
1617 if (ctype_isComplex (c))
1618 {
1619 ctbase ctb = ctype_getCtbaseSafe (c);
1620 bool res = ctbase_isPointer (ctb);
1621
1622 return res;
1623 }
1624 else
1625 {
1626 bool res = ctentry_isPointer (ctype_getCtentry (c));
1627
1628 return res;
1629 }
1630}
1631
1632/*
1633** ctype_isArray
1634**
1635** true for C and LCL array's
1636*/
1637
1638bool
1639ctype_isArray (ctype c)
1640{
1641 if (ctype_isElips (c)) return FALSE;
1642
1643 if (ctype_isComplex (c))
1644 return (ctbase_isEitherArray (ctype_getCtbaseSafe (c)));
1645 else
1646 return (ctentry_isArray (ctype_getCtentry (c)));
1647}
1648
1649bool ctype_isIncompleteArray (ctype c)
1650{
1651 return (ctype_isArray (c) && !ctype_isFixedArray (c));
1652}
1653
1654bool ctype_isFixedArray (ctype c)
1655{
1656 if (ctype_isElips (c)) return FALSE;
1657
1658 return (ctbase_isFixedArray (ctype_getCtbaseSafe (c)));
1659}
1660
1661bool
1662ctype_isArrayPtr (ctype c)
1663{
1664 return ((ctype_isArray (c)) || (ctype_isPointer (c)));
1665}
1666
1667typeId
1668ctype_typeId (ctype c)
1669{
1670 return (ctbase_typeId (ctype_getCtbase (c)));
1671}
1672
1673cstring
1674ctype_unparseDeclaration (ctype c, /*@only@*/ cstring name)
1675{
1676 llassert (!(ctype_isElips (c) || ctype_isMissingParamsMarker (c)));
28bf4b0b 1677
1678 if (ctype_isUnknown (c))
1679 {
1680 return message ("? %q", name);
1681 }
1682 else
1683 {
1684 return (ctbase_unparseDeclaration (ctype_getCtbase (c), name));
1685 }
616915dd 1686}
1687
1688cstring
1689ctype_unparse (ctype c)
1690{
1691 if (ctype_isElips (c))
1692 {
1693 return cstring_makeLiteralTemp ("...");
1694 }
1695 else if (ctype_isMissingParamsMarker (c))
1696 {
1697 return cstring_makeLiteralTemp ("-");
1698 }
28bf4b0b 1699 else if (ctype_isUnknown (c))
1700 {
1701 return cstring_makeLiteralTemp ("?");
1702 }
616915dd 1703 else
1704 {
1705 /*@-modobserver@*/
1706 return (ctentry_doUnparse (ctype_getCtentry (c)));
1707 /*@=modobserver@*/
1708 }
1709}
1710
1711cstring
1712ctype_unparseSafe (ctype c)
1713{
1714 if (ctype_isElips (c))
1715 {
1716 return cstring_makeLiteralTemp ("...");
1717 }
1718 else if (ctype_isMissingParamsMarker (c))
1719 {
1720 return cstring_makeLiteralTemp ("-");
1721 }
1722 else
1723 {
1724 cstring ret;
1725
1726 if /*@+enumint@*/ (c >= CTK_PLAIN && c < cttab.size) /*@=enumint@*/
1727 {
1728 ctentry cte = ctype_getCtentry (c);
1729
1730 if (cstring_isDefined (cte->unparse))
1731 {
1732 return (cte->unparse);
1733 }
1734 }
1735
1736 ret = message ("[%d]", (int) c);
1737 cstring_markOwned (ret);
1738 return ret;
1739 }
1740}
1741
1742cstring
1743ctype_unparseDeep (ctype c)
1744{
1745 if (ctype_isElips (c))
1746 {
1747 return cstring_makeLiteralTemp ("...");
1748 }
1749 if (ctype_isMissingParamsMarker (c))
1750 {
1751 return cstring_makeLiteralTemp ("-");
1752 }
1753
1754 return (ctentry_doUnparseDeep (ctype_getCtentry (c)));
1755}
1756
1757ctype
1758ctype_undump (char **c)
1759{
28bf4b0b 1760 return ((ctype) reader_getInt (c)); /* check its valid? */
616915dd 1761}
1762
1763cstring
1764ctype_dump (ctype c)
1765{
1766 DPRINTF (("Ctype dump: %s", ctype_unparse (c)));
1767
1768 if (c < 0)
1769 {
1770 /* Handle invalid types in a kludgey way. */
1771 return (message ("0"));
1772 }
1773
1774 if (ctype_isUA (c))
1775 {
1776 cstring tname = usymtab_getTypeEntryName
1777 (usymtab_convertId (ctype_typeId (c)));
1778
1779 if (cstring_equal (tname, context_getBoolName ()))
1780 {
1781 cstring_free (tname);
1782 return (message ("%d", ctype_bool));
1783 }
1784
1785 cstring_free (tname);
1786 }
1787
1788 DPRINTF (("Returning: %d", c));
1789 return (message ("%d", c));
1790}
1791
1792ctype
1793ctype_getBaseType (ctype c)
1794{
1795 ctentry cte = ctype_getCtentry (c);
1796
1797 switch (ctentry_getKind (cte))
1798 {
1799 case CTK_UNKNOWN:
616915dd 1800 case CTK_INVALID:
616915dd 1801 case CTK_PLAIN:
1802 return c;
1803 case CTK_PTR:
1804 case CTK_ARRAY:
1805 return (ctype_getBaseType (ctype_baseArrayPtr (c)));
1806 case CTK_COMPLEX:
1807 {
1808 ctbase ctb = cte->ctbase;
1809
1810 if (ctbase_isDefined (ctb))
1811 {
28bf4b0b 1812 /*@access ctbase@*/
616915dd 1813 switch (ctb->type)
1814 {
1815 case CT_UNKNOWN:
1816 case CT_PRIM:
1817 case CT_USER:
1818 case CT_ENUM:
1819 case CT_ENUMLIST:
1820 case CT_BOOL:
1821 case CT_ABST:
1822 case CT_FCN:
1823 case CT_STRUCT:
1824 case CT_UNION:
1825 case CT_EXPFCN:
1826 return c;
1827 case CT_PTR:
1828 case CT_ARRAY:
1829 return (ctype_getBaseType (ctb->contents.base));
1830 case CT_FIXEDARRAY:
1831 return (ctype_getBaseType (ctb->contents.farray->base));
1832 case CT_CONJ: /* base type of A conj branch? */
1833 return (ctype_getBaseType (ctb->contents.conj->a));
1834 }
28bf4b0b 1835 /*@noaccess ctbase@*/
616915dd 1836 }
1837 else
1838 {
1839 return c;
1840 }
1841 }
1842 default:
1843 llbuglit ("ctype_newBase: bad case");
1844 }
1845 llcontbuglit ("ctype_getBaseType: unreachable code");
1846 return ((ctype)NULL);
1847}
1848
1849ctype
1850ctype_adjustPointers (int np, ctype c)
1851{
1852
1853 if (ctype_isFunction (c))
1854 {
1855 c = ctype_makeParamsFunction
28bf4b0b 1856 (ctype_adjustPointers (np, ctype_getReturnType (c)),
616915dd 1857 uentryList_copy (ctype_argsFunction (c)));
1858 }
1859 else
1860 {
1861 /* fix this should not use getBaseType ??? */
1862 ctype cb = ctype_getBaseType (c);
1863
1864 while (np > 0)
1865 {
1866 cb = ctype_makePointer (cb);
1867 np--;
1868 }
1869 c = ctype_newBase (c, cb);
1870 }
1871
1872 return (c);
1873}
1874
1875
1876enumNameList
1877ctype_elist (ctype c)
1878{
1879 return (ctbase_elist (ctype_getCtbase (c)));
1880}
1881
1882bool
1883ctype_isFirstVoid (ctype c)
1884{
1885 return (c == CTX_VOID || (ctype_isConj (c) && ctype_isFirstVoid (ctype_getConjA (c))));
1886}
1887
1888ctype
1889ctype_createEnum (/*@keep@*/ cstring tag, /*@keep@*/ enumNameList el)
1890{
1891 return (cttable_addComplex (ctbase_createEnum (tag, el)));
1892}
1893
1894bool
1895ctype_isEnum (ctype c)
1896{
1897 return (ctype_isComplex (c) && ctbase_isEnum (ctype_getCtbase (c)));
1898}
1899
1900cstring
1901ctype_enumTag (ctype c)
1902{
1903 llassert (ctype_isEnum (c));
1904
1905 return (ctbase_enumTag (ctype_getCtbaseSafe (c)));
1906}
1907
1908bool
1909ctype_isStruct (ctype c)
1910{
1911 return (ctype_isComplex (c) && ctbase_isStruct (ctype_getCtbaseSafe (c)));
1912}
1913
1914bool
1915ctype_isUnion (ctype c)
1916{
1917 return (ctype_isComplex (c) && ctbase_isUnion (ctype_getCtbaseSafe (c)));
1918}
1919
1920ctype
1921ctype_resolveNumerics (ctype c1, ctype c2)
1922{
1923 /*
1924 ** returns longest type of c1 and c2
1925 */
1926
1927 if (c1 == c2) return c1;
1928
1929 c1 = ctype_realType (c1);
1930 c2 = ctype_realType (c2);
1931
1932 if (ctype_isEnum (c1)) c1 = ctype_unknown;
1933 if (ctype_isEnum (c2)) c2 = ctype_int;
1934
1935 if (c1 == ctype_ldouble || c2 == ctype_ldouble) return ctype_ldouble;
28bf4b0b 1936
1937 /* 2001-06-08: This fix provided by Jim Zelenka. */
1938 if (c1 == ctype_llint || c2 == ctype_llint) return ctype_llint;
1939 if (c1 == ctype_ullint || c2 == ctype_ullint) return ctype_ullint;
1940
616915dd 1941 if (c1 == ctype_ulint || c2 == ctype_ulint) return ctype_ulint;
1942 if (c1 == ctype_lint || c2 == ctype_lint) return ctype_lint;
1943 if (c1 == ctype_uint || c2 == ctype_uint) return ctype_uint;
1944 if (c1 == ctype_int || c2 == ctype_int) return ctype_int;
28bf4b0b 1945
1946 /* 2001-06-08: This fix provided by Jim Zelenka. */
1947 if (c1 == ctype_usint || c2 == ctype_usint) return ctype_usint;
1948
616915dd 1949 if (c1 == ctype_sint || c2 == ctype_sint) return ctype_sint;
28bf4b0b 1950
616915dd 1951 if (c1 == ctype_uchar || c2 == ctype_uchar) return ctype_uchar;
1952 if (c1 == ctype_char || c2 == ctype_char) return ctype_char;
1953
1954 if (ctype_isKnown (c1)) return c1;
1955 else return c2;
1956}
1957
1958bool
1959ctype_isStructorUnion (ctype c)
1960{
1961 return (ctype_isStruct (c) || ctype_isUnion (c));
1962}
1963
1964ctype
1965ctype_fixArrayPtr (ctype c)
1966{
1967 if (ctype_isArray (c))
1968 {
1969 return (ctype_makePointer (ctype_baseArrayPtr (c)));
1970 }
1971 else
1972 return c;
1973}
1974
1975/*
1976** createUnnamedStruct/Union
1977**
1978** check if it corresponds to an existing LCL-specified unnamed struct
1979** otherwise, give it a new tag
1980*/
1981
1982ctype
1983ctype_createUnnamedStruct (/*@only@*/ uentryList f)
1984{
1985 ctype ret = usymtab_structFieldsType (f);
1986
28bf4b0b 1987 DPRINTF (("unnamed struct: %s", ctype_unparse (ret)));
1988
616915dd 1989 if (ctype_isDefined (ret))
1990 {
1991 uentryList_free (f);
1992 return ret;
1993 }
1994 else
1995 {
1996 cstring ft = fakeTag ();
1997 ctype ct = ctype_createStruct (cstring_copy (ft), f);
1998 uentry ue = uentry_makeStructTagLoc (ft, ct);
28bf4b0b 1999
2000 DPRINTF (("Unnamed struct: %s", uentry_unparseFull (ue)));
2001 ue = usymtab_supGlobalEntryReturn (ue);
2002 DPRINTF (("After Unnamed struct: %s", uentry_unparseFull (ue)));
2003
616915dd 2004 cstring_free (ft);
2005 return (ct);
2006 }
2007}
2008
2009ctype
2010ctype_createUnnamedUnion (/*@only@*/ uentryList f)
2011{
2012 ctype ret = usymtab_unionFieldsType (f);
2013
2014 if (ctype_isDefined (ret))
2015 {
2016 uentryList_free (f);
2017 return ret;
2018 }
2019 else
2020 {
2021 cstring ft = fakeTag ();
2022 ctype ct = ctype_createUnion (cstring_copy (ft), f);
2023 uentry ue = uentry_makeUnionTagLoc (ft, ct);
2024
2025 usymtab_supGlobalEntry (ue);
2026 cstring_free (ft);
2027 return (ct);
2028 }
2029}
2030
28bf4b0b 2031bool
2032ctype_isUnnamedSU (ctype c)
2033{
2034 if (ctype_isSU (c))
2035 {
2036 return ctbase_isUnnamedSU (ctype_getCtbase (c));
2037 }
2038 else
2039 {
2040 return FALSE;
2041 }
2042}
2043
616915dd 2044ctype
2045ctype_createForwardStruct (cstring n)
2046{
2047 uentry ue = uentry_makeStructTag (n, ctype_unknown, fileloc_undefined);
2048 ctype ct = usymtab_supForwardTypeEntry (ue);
2049
2050 cstring_free (n);
2051 return (ct);
2052}
2053
2054ctype
2055ctype_createForwardUnion (cstring n)
2056{
2057 uentry ue = uentry_makeUnionTag (n, ctype_unknown, fileloc_undefined);
2058 ctype ct = usymtab_supForwardTypeEntry (ue);
2059
2060 cstring_free (n);
2061 return (ct);
2062}
2063
2064ctype
2065ctype_removePointers (ctype c)
2066{
2067 ctype oldc;
2068
28bf4b0b 2069 while (ctype_isKnown (c) && ctype_isArrayPtr (c))
616915dd 2070 {
2071 oldc = c;
2072 c = ctype_baseArrayPtr (c);
2073 llassert (c != oldc);
2074 }
2075
2076 return (c);
2077}
2078
2079bool ctype_isMutable (ctype t)
2080{
2081 if (ctype_isUA (t))
2082 {
2083 return (uentry_isMutableDatatype
2084 (usymtab_getTypeEntry (ctype_typeId (t))));
2085 }
2086 else
2087 {
2088 return (ctype_isPointer (ctype_realType (t)));
28bf4b0b 2089 /*!! || ctype_isStructorUnion (ctype_realType (t))); */
616915dd 2090 }
2091}
2092
2093bool ctype_isRefCounted (ctype t)
2094{
2095 if (ctype_isUA (t))
2096 {
2097 return (uentry_isRefCountedDatatype
2098 (usymtab_getTypeEntry (ctype_typeId (t))));
2099 }
2100
2101 return FALSE;
2102}
2103
2104bool ctype_isVisiblySharable (ctype t)
2105{
2106 if (ctype_isUnknown (t)) return TRUE;
2107
2108 if (ctype_isConj (t))
2109 {
2110 return (ctype_isVisiblySharable (ctype_getConjA (t))
2111 || ctype_isVisiblySharable (ctype_getConjB (t)));
2112 }
2113
2114 if (ctype_isMutable (t))
2115 {
2116 if (ctype_isUA (t))
2117 {
2118 ctype rt = ctype_realType (t);
2119
2120 if (rt == t)
2121 {
2122 return TRUE;
2123 }
2124 else
2125 {
2126 return ctype_isVisiblySharable (rt);
28bf4b0b 2127
616915dd 2128 }
2129 }
2130 else
2131 {
2132 return TRUE;
2133 }
2134 }
2135
2136 return FALSE;
2137}
2138
2139# if 0
2140/* Replaced by ctype_isMutable (more sensible) */
2141bool ctype_canAlias (ctype ct)
2142{
2143 /* can ct refer to memory locations?
2144 ** ==> a pointer or a mutable abstract type
2145 ** arrays?
2146 */
2147
2148 ctype tr = ctype_realType (ct);
2149
2150 return (ctype_isPointer (tr) || ctype_isMutable (ct) || ctype_isStructorUnion (tr));
2151}
2152# endif
2153
2154/*
2155** c1 is the dominant type; c2 is the modifier type
2156**
2157** eg. double + long int => long double
2158*/
2159
2160ctype ctype_combine (ctype dominant, ctype modifier)
2161{
2162 DPRINTF (("Combine: %s + %s",
2163 ctype_unparse (dominant),
2164 ctype_unparse (modifier)));
2165
2166 if (ctype_isConj (dominant))
2167 {
2168 ctype res;
2169
2170 if (ctype_isExplicitConj (dominant))
2171 {
2172 res = ctype_makeExplicitConj (ctype_combine (ctype_getConjA (dominant),
2173 modifier),
2174 ctype_getConjB (dominant));
2175 }
2176 else
2177 {
2178 res = ctype_makeConj (ctype_combine (ctype_getConjA (dominant),
2179 modifier),
2180 ctype_getConjB (dominant));
2181 }
2182
2183 return res;
2184 }
2185
2186 if (ctype_isUnknown (modifier))
2187 {
2188 return dominant;
2189 }
2190 else if (ctype_isUnknown (dominant))
2191 {
2192 return modifier;
2193 }
2194 else
2195 {
2196 if (ctype_isEnum (dominant)) dominant = ctype_int;
2197 if (ctype_isEnum (modifier)) modifier = ctype_int;
2198
2199 if (modifier == ctype_uint)
2200 {
2201 if (dominant == ctype_int) return ctype_uint;
2202 if (dominant == ctype_lint) return ctype_ulint;
2203 if (dominant == ctype_sint) return ctype_usint;
2204 if (dominant == ctype_char) return ctype_uchar;
2205
2206 /* evs 2000-07-28: added this line */
2207 if (dominant == ctype_llint) return ctype_ullint;
2208
2209 if ((dominant == ctype_uint) || dominant == ctype_uchar)
2210 {
2211 voptgenerror (FLG_DUPLICATEQUALS,
2212 message ("Duplicate unsigned qualifier"),
2213 g_currentloc);
2214
2215 return ctype_uint;
2216 }
2217 else
2218 {
2219 voptgenerror (FLG_DUPLICATEQUALS,
2220 message ("Type qualifier unsigned used with %s",
2221 ctype_unparse (dominant)),
2222 g_currentloc);
2223
2224 return dominant;
2225 }
2226 }
2227 else if (modifier == ctype_llint)
2228 {
2229 if (dominant == ctype_int)
2230 {
2231 return ctype_llint;
2232 }
2233
2234 voptgenerror (FLG_DUPLICATEQUALS,
2235 message ("Duplicate long qualifier on non-int"),
2236 g_currentloc);
2237 }
2238 else if (modifier == ctype_lint)
2239 {
2240 if (dominant == ctype_int) return ctype_lint;
2241 if (dominant == ctype_uint) return ctype_ulint;
2242 if (dominant == ctype_double) return ctype_ldouble;
2243
2244 if (dominant == ctype_lint || dominant == ctype_ulint
2245 || dominant == ctype_sint || dominant == ctype_usint
2246 || dominant == ctype_ldouble)
2247 {
2248 if (dominant == ctype_lint)
2249 {
2250 /* long long not supported by ANSI */
2251 return ctype_llint;
2252 }
2253
28bf4b0b 2254 /* ++jimz */
2255 if (dominant == ctype_ulint)
2256 {
2257 /* unsigned long long not supported by ANSI */
2258 return ctype_ullint;
2259 }
2260 /* ==jimz */
2261
616915dd 2262 if (dominant == ctype_sint || dominant == ctype_usint)
2263 {
2264 if (!context_getFlag (FLG_IGNOREQUALS))
2265 {
2266 llerrorlit (FLG_SYNTAX,
2267 "Contradictory long and short type qualifiers");
2268 }
2269 }
2270 else
2271 {
2272 voptgenerror (FLG_DUPLICATEQUALS,
2273 message ("Duplicate long qualifier"),
2274 g_currentloc);
2275 }
2276
2277 return ctype_lint;
2278 }
2279 }
2280 else if (modifier == ctype_sint)
2281 {
2282 if (dominant == ctype_int) return ctype_sint;
2283 if (dominant == ctype_uint) return ctype_usint;
2284
2285 if (dominant == ctype_sint || dominant == ctype_usint)
2286 {
2287 voptgenerror (FLG_DUPLICATEQUALS,
2288 message ("Duplicate short qualifier"),
2289 g_currentloc);
2290 return ctype_uint;
2291 }
2292 else if (dominant == ctype_lint)
2293 {
2294 if (!context_getFlag (FLG_IGNOREQUALS))
2295 {
2296 llerrorlit (FLG_SYNTAX,
2297 "Contradictory long and short type qualifiers");
2298 }
2299
2300 return dominant;
2301 }
28bf4b0b 2302/* ++jimz */
2303 else if (dominant == ctype_llint)
2304 {
2305 if (!context_getFlag (FLG_IGNOREQUALS))
2306 {
2307 llerrorlit (FLG_SYNTAX,
2308 "Contradictory long long and short type qualifiers");
2309 }
2310
2311 return dominant;
2312 }
2313/* ==jimz */
616915dd 2314 else
2315 {
2316 if (!context_getFlag (FLG_IGNOREQUALS))
2317 {
2318 llerror (FLG_SYNTAX,
2319 message ("Type qualifier short used with %s",
2320 ctype_unparse (dominant)));
2321 }
2322
2323 return dominant;
2324 }
2325 }
2326 else if (modifier == ctype_ulint)
2327 {
2328 if (dominant == ctype_int) return modifier;
2329
2330 if (dominant == ctype_lint || dominant == ctype_ulint)
2331 {
2332 voptgenerror (FLG_DUPLICATEQUALS,
2333 message ("Duplicate long qualifier"),
2334 g_currentloc);
2335
2336 return modifier;
2337 }
2338
2339 if (dominant == ctype_uint || dominant == ctype_usint)
2340 {
2341 voptgenerror (FLG_DUPLICATEQUALS,
2342 message ("Duplicate unsigned qualifier"),
2343 g_currentloc);
2344
2345 return modifier;
2346 }
2347
2348 if (dominant == ctype_sint || dominant == ctype_usint)
2349 {
2350 if (!context_getFlag (FLG_IGNOREQUALS))
2351 {
2352 llerrorlit (FLG_SYNTAX,
2353 "Contradictory long and short type qualifiers");
2354 }
2355
2356 return dominant;
2357 }
2358
2359 if (!context_getFlag (FLG_IGNOREQUALS))
2360 {
2361 llerror (FLG_SYNTAX,
2362 message ("Type qualifiers unsigned long used with %s",
2363 ctype_unparse (dominant)));
2364 }
2365
2366 return dominant;
2367 }
2368 else if (modifier == ctype_usint)
2369 {
2370 if (dominant == ctype_int) return modifier;
2371
2372 if (dominant == ctype_sint || dominant == ctype_usint)
2373 {
2374 voptgenerror (FLG_DUPLICATEQUALS,
2375 message ("Duplicate short qualifier"),
2376 g_currentloc);
2377 return modifier;
2378 }
2379
2380 if (dominant == ctype_uint)
2381 {
2382 voptgenerror (FLG_DUPLICATEQUALS,
2383 message ("Duplicate unsigned qualifier"),
2384 g_currentloc);
2385
2386 return modifier;
2387 }
2388
2389 if (dominant == ctype_lint || dominant == ctype_ulint
2390 || dominant == ctype_llint)
2391 {
2392 if (!context_getFlag (FLG_IGNOREQUALS))
2393 {
2394 llerrorlit (FLG_SYNTAX,
2395 "Contradictory long and short type qualifiers");
2396 }
2397
2398 return dominant;
2399 }
2400
2401 if (!context_getFlag (FLG_IGNOREQUALS))
2402 {
2403 llerror (FLG_SYNTAX,
2404 message ("Type qualifiers unsigned short used with %s",
2405 ctype_unparse (dominant)));
2406 }
2407
2408 return dominant;
2409 }
2410 else
2411 {
2412 ;
2413 }
2414
2415 return dominant;
2416 }
2417}
2418
2419ctype ctype_resolve (ctype c)
2420{
2421 if (ctype_isUnknown (c)) return ctype_int;
2422 return c;
2423}
2424
2425ctype ctype_fromQual (qual q)
2426{
2427 if (qual_isSigned (q)) return ctype_int;
2428 if (qual_isUnsigned (q)) return ctype_uint;
2429 if (qual_isLong (q)) return ctype_lint;
2430 if (qual_isShort (q)) return ctype_sint;
2431
2432 llcontbug (message ("ctype_fromQual: invalid qualifier: %s", qual_unparse (q)));
2433 return ctype_unknown;
2434}
2435
2436bool
2437ctype_isAnyFloat (ctype c)
2438{
2439 return (cprim_isAnyReal (ctype_toCprim (c)));
2440}
2441
2442bool
2443ctype_isUnsigned (ctype c)
2444{
2445 if (ctype_isConj (c))
2446 return (ctype_isUnsigned (ctype_getConjA (c)) ||
2447 ctype_isUnsigned (ctype_getConjB (c)));
2448
2449 return (c == ctype_uint || c == ctype_uchar
2450 || c == ctype_usint || c == ctype_ulint
28bf4b0b 2451 || c == ctype_ullint
616915dd 2452 || c == ctype_unsignedintegral);
2453}
2454
28bf4b0b 2455/* ++jimz */
2456static bool
2457ctype_isLongLong (ctype c)
2458{
2459 if (ctype_isConj (c))
2460 return (ctype_isLongLong (ctype_getConjA (c)) ||
2461 ctype_isLongLong (ctype_getConjB (c)));
2462
2463 return (c == ctype_llint || c == ctype_ullint);
2464}
2465/* ==jimz */
2466
616915dd 2467static bool
2468ctype_isLong (ctype c)
2469{
2470 if (ctype_isConj (c))
2471 return (ctype_isLong (ctype_getConjA (c)) ||
2472 ctype_isLong (ctype_getConjB (c)));
2473
2474 return (c == ctype_lint || c == ctype_ulint);
2475}
2476
2477static bool
2478ctype_isShort (ctype c)
2479{
2480 if (ctype_isConj (c))
2481 return (ctype_isShort (ctype_getConjA (c)) ||
2482 ctype_isShort (ctype_getConjB (c)));
2483
2484 return (c == ctype_sint || c == ctype_usint);
2485}
2486
2487bool
2488ctype_isStackAllocated (ctype c)
2489{
2490 ctype ct = ctype_realType (c);
2491
2492 if (ctype_isConj (ct))
2493 return (ctype_isStackAllocated (ctype_getConjA (ct)) ||
2494 ctype_isStackAllocated (ctype_getConjB (ct)));
2495
2496 return (ctype_isArray (c) || ctype_isSU (c));
2497}
2498
2499static bool ctype_isMoreUnsigned (ctype c1, ctype c2)
2500{
2501 return (ctype_isUnsigned (c1) && !ctype_isUnsigned (c2));
2502}
2503
2504static bool ctype_isLonger (ctype c1, ctype c2)
2505{
28bf4b0b 2506 /* 2001-06-10: Fix for long long's provided by Jim Zelenka */
616915dd 2507 return ((ctype_isDouble (c1) && !ctype_isDouble (c2))
28bf4b0b 2508 || (ctype_isLongLong (c1) && !ctype_isLongLong (c2))
2509 || (ctype_isLong (c1)
2510 && (!ctype_isLong (c2)) && (!ctype_isLongLong (c2)))
616915dd 2511 || (ctype_isShort (c2) && !ctype_isShort (c1)));
2512}
2513
2514ctype
2515ctype_widest (ctype c1, ctype c2)
2516{
28bf4b0b 2517 if (ctype_isMoreUnsigned (c2, c1) || ctype_isLonger (c2, c1))
616915dd 2518 {
2519 return c2;
2520 }
2521 else
2522 {
2523 return c1;
2524 }
2525}
2526
28bf4b0b 2527static /*@observer@*/ ctbase ctype_getCtbase (ctype c)
2528{
2529 /*@+enumint@*/
2530 if (c >= 0 && c < cttab.size)
2531 {
2532 return (cttab.entries[c]->ctbase);
2533 }
2534 else
2535 {
2536 if (c == ctype_unknown)
2537 llbuglit ("ctype_getCtbase: ctype unknown");
2538 if (c == ctype_undefined)
2539 llbuglit ("ctype_getCtbase: ctype undefined");
2540 if (c == ctype_dne)
2541 llbuglit ("ctype_getCtbase: ctype dne");
2542 if (c == ctype_elipsMarker)
2543 llbuglit ("ctype_getCtbase: elips marker");
2544
2545 llfatalbug (message ("ctype_getCtbase: ctype out of range: %d", c));
2546 BADEXIT;
2547 }
2548
2549 /*@=enumint@*/
2550}
2551
2552static /*@notnull@*/ /*@observer@*/ ctbase
2553ctype_getCtbaseSafe (ctype c)
2554{
2555 ctbase res = ctype_getCtbase (c);
2556
2557 llassert (ctbase_isDefined (res));
2558 return res;
2559}
2560
2561/*
2562** ctentry
2563*/
2564
2565static ctentry
2566ctype_getCtentry (ctype c)
2567{
2568 static /*@only@*/ ctentry errorEntry = NULL;
2569
2570 if (cttab.size == 0)
2571 {
2572 if (errorEntry == NULL)
2573 {
2574 errorEntry = ctentry_makeNew (CTK_UNKNOWN, ctbase_undefined);
2575 }
2576
2577 return errorEntry;
2578 }
2579
2580 /*@+enumint@*/
2581 if (c >= CTK_PLAIN && c < cttab.size)
2582 {
2583 return (cttab.entries[c]);
2584 }
2585 else if (c == CTK_UNKNOWN)
2586 llcontbuglit ("ctype_getCtentry: ctype unknown");
2587 else if (c == CTK_INVALID)
2588 llcontbuglit ("ctype_getCtentry: ctype invalid (ctype_undefined)");
2589 else if (c == CTK_DNE)
2590 llcontbuglit ("ctype_getCtentry: ctype dne");
2591 else if (c == CTK_ELIPS)
2592 llcontbuglit ("ctype_getCtentry: ctype elipsis");
2593 else if (c == CTK_MISSINGPARAMS)
2594 llcontbuglit ("ctype_getCtentry: ctype missing params");
2595 else
2596 llbug (message ("ctype_getCtentry: ctype out of range: %d", c));
2597
2598 return (cttab.entries[ctype_unknown]);
2599 /*@=enumint@*/
2600}
2601
616915dd 2602/*drl 11/28/2000 */
2603/* requires that the type is an fixed array */
2604/* return the size of the array */
2605
2606long int ctype_getArraySize (ctype c)
2607{
28bf4b0b 2608 long int size;
616915dd 2609 ctentry cte = ctype_getCtentry (c);
2610 ctbase ctb;
2611 llassert ( (ctentry_getKind (cte) == CTK_COMPLEX) || (ctentry_getKind(cte) == CTK_ARRAY) );
2612
2613 ctb = cte->ctbase;
2614
28bf4b0b 2615 size = ctbase_getArraySize (ctb);
616915dd 2616
28bf4b0b 2617 DPRINTF(( message("ctype_getArraySize: got fixed array size of %d ", (int)size) ));
2618 return size;
616915dd 2619}
28bf4b0b 2620
This page took 3.047819 seconds and 5 git commands to generate.