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