]> andersk Git - splint.git/blame - src/ctype.c
Updated README version number. (Testing sourceforge)
[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{
2209bcb7 801 return (ctype_isInt (c) || ctype_isReal (c) || ctype_isEnum (c)
802 /* evans 2001-10-05: added this: */
803 || ctype_isArbitraryIntegral (c));
616915dd 804}
805
806
807/*
808** real predicates
809**
810** work on actual type in current context
811*/
812
813bool
814ctype_isRealNumeric (ctype c)
815{
816 if (ctype_isPlain (c))
817 return (ctype_isNumeric (ctype_realType (c)));
818 if (ctype_isConj (c))
819 return (ctype_isRealNumeric (ctype_getConjA (c)) ||
820 ctype_isRealNumeric (ctype_getConjB (c)));
821 else
822 return FALSE;
823}
824
825bool
826ctype_isRealInt (ctype c)
827{
828 if (ctype_isPlain (c))
829 return (ctype_isInt (ctype_realType (c)));
830 else if (ctype_isConj (c))
831 return (ctype_isRealInt (ctype_getConjA (c)) ||
832 ctype_isRealInt (ctype_getConjB (c)));
833 else
834 {
835 if (ctype_isEnum (c) && context_msgEnumInt ()) return TRUE;
836 return FALSE;
837 }
838}
839
840bool
841ctype_isRealVoid (ctype c)
842{
843 if (ctype_isPlain (c))
844 {
845 return (ctype_isVoid (ctype_realType (c)));
846 }
847 else if (ctype_isConj (c))
848 {
849 return (ctype_isRealVoid (ctype_getConjA (c)) ||
850 ctype_isRealVoid (ctype_getConjB (c)));
851 }
852 else
853 {
854 return FALSE;
855 }
856}
857
858bool
859ctype_isRealBool (ctype c)
860{
861 if (ctype_isPlain (c))
862 {
863 return (ctype_isBool (ctype_realishType (c)));
864 }
865 else if (ctype_isConj (c))
866 {
867 return (ctype_isRealBool (ctype_getConjA (c)) ||
868 ctype_isRealBool (ctype_getConjB (c)));
869 }
870 else
871 {
872 return FALSE;
873 }
874}
875
876bool
877ctype_isRealPointer (ctype c)
878{
879 if (ctype_isConj (c))
880 return (ctype_isRealPointer (ctype_getConjA (c)) ||
881 ctype_isRealPointer (ctype_getConjB (c)));
882 return (ctype_isPointer (ctype_realType (c)));
883}
884
885bool
886ctype_isRealSU (ctype c)
887{
888 if (ctype_isConj (c))
889 {
890 return (ctype_isRealSU (ctype_getConjA (c)) ||
891 ctype_isRealSU (ctype_getConjB (c)));
892 }
28bf4b0b 893
894 DPRINTF (("Real su: %s / %s", ctype_unparse (c), ctype_unparse (ctype_realType (c))));
616915dd 895 return (ctype_isStructorUnion (ctype_realType (c)));
896}
897
898bool
899ctype_isRealArray (ctype c)
900{
901 if (ctype_isConj (c))
902 return (ctype_isRealArray (ctype_getConjA (c)) ||
903 ctype_isRealArray (ctype_getConjB (c)));
904 return (ctype_isArray (ctype_realType (c)));
905}
906
907bool
908ctype_isRealAP (ctype c)
909{
910 if (ctype_isConj (c))
911 return (ctype_isRealAP (ctype_getConjA (c)) ||
912 ctype_isRealAP (ctype_getConjB (c)));
913 return (ctype_isAP (ctype_realType (c)));
914}
915
916bool
917ctype_isRealFunction (ctype c)
918{
919 if (ctype_isConj (c))
920 return (ctype_isRealFunction (ctype_getConjA (c)) ||
921 ctype_isRealFunction (ctype_getConjB (c)));
922 return (ctype_isFunction (ctype_realType (c)));
923}
924
925bool
926ctype_isDirectInt (ctype c)
927{
928 return (c == CTX_INT || c == CTX_UINT || c == CTX_SINT || c == CTX_ULINT || c == CTX_USINT);
929}
930
931/*
932** forceful predicates
933**
934** take *ctype; if its a conjunct, and there is a match replace with match only.
935** if both match, still conjunct
936*/
937
938static bool
939 ctype_isForcePred (ctype * c, bool (pred) (ctype))
940{
941 if (ctype_isConj (*c))
942 {
943 ctype cbr = ctype_getConjA (*c);
944
945 if ((*pred) (cbr))
946 {
947 if ((*pred) (ctype_getConjB (*c)))
948 {
949 ;
950 }
951 else
952 {
953 *c = cbr;
954 }
955
956 return TRUE;
957 }
958 else
959 {
960 if ((*pred) (cbr = ctype_getConjB (*c)))
961 {
962 *c = cbr;
963 return TRUE;
964 }
965 }
966 }
967
968 return ((*pred) (*c));
969}
970
971bool
972ctype_isForceRealNumeric (ctype * c)
973{
974 return (ctype_isForcePred (c, ctype_isRealNumeric));
975}
976
977bool
978ctype_isForceRealInt (ctype * c)
979{
980 return (ctype_isForcePred (c, ctype_isRealInt));
981}
982
983bool
984ctype_isForceRealBool (ctype * c)
985{
986 return (ctype_isForcePred (c, ctype_isRealBool));
987}
988
989/*
990** conjuncts
991**
992** save int/char, int/bool, other random conjuncts
993*/
994
995static ctype
996ctype_makeConjAux (ctype c1, ctype c2, bool isExplicit)
997{
998 if (ctype_isBogus (c1) || ctype_isUndefined (c1))
999 {
1000 return c2;
1001 }
1002 else if (ctype_isBogus (c2) || ctype_isUndefined (c2))
1003 {
1004 return c1;
1005 }
1006 else
1007 {
1008 if (isExplicit)
1009 {
1010 return (ctype_makeExplicitConj (c1, c2));
1011 }
1012 else
1013 {
1014 return (ctype_makeConj (c1, c2));
1015 }
1016 }
1017}
1018
1019ctype
1020ctype_makeExplicitConj (ctype c1, ctype c2)
1021{
1022 if (ctype_isFunction (c1) && !ctype_isFunction (c2))
1023 {
28bf4b0b 1024 ctype ret = ctype_makeExplicitConj (ctype_getReturnType (c1), c2);
616915dd 1025
1026 return ctype_makeFunction (ret, uentryList_copy (ctype_getParams (c1)));
1027 }
1028 else if (ctype_isFunction (c2) && !ctype_isFunction (c1))
1029 {
28bf4b0b 1030 ctype ret = ctype_makeExplicitConj (c1, ctype_getReturnType (c2));
616915dd 1031
1032 return ctype_makeFunction (ret, uentryList_copy (ctype_getParams (c2)));
1033 }
1034 else
1035 {
1036 return (cttable_addComplex (ctbase_makeConj (c1, c2, TRUE)));
1037 }
1038}
1039
1040static ctype ic = ctype_unknown; /* int | char */
1041static ctype ib = ctype_unknown; /* int | bool */
1042static ctype ifl = ctype_unknown; /* int | float */
1043static ctype ibf = ctype_unknown; /* int | bool | float */
1044static ctype ibc = ctype_unknown; /* int | bool | char */
1045static ctype iv = ctype_unknown; /* int | void * */
1046static ctype ivf = ctype_unknown; /* int | void * | float */
1047static ctype ivb = ctype_unknown; /* int | void * | bool */
1048static ctype ivbf = ctype_unknown; /* int | void * | bool | float */
1049static ctype cuc = ctype_unknown; /* char | unsigned char */
1050
1051static void
1052ctype_recordConj (ctype c)
1053{
1054 ctype c1, c2;
1055
1056 llassert (ctype_isConj (c));
1057
1058 c1 = ctype_getConjA (c);
1059 c2 = ctype_getConjB (c);
1060
1061 /* No, can't swap!
1062 if (c2 == ctype_int && c1 != ctype_int)
1063 {
1064 ctype tmp;
1065
1066 tmp = c1;
1067 c1 = c2;
1068 c2 = tmp;
1069 }
1070 */
1071
1072 if (c1 == ctype_int)
1073 {
1074 if (c2 == ctype_char)
1075 {
1076 llassert (ic == ctype_unknown);
1077 ic = c;
1078 }
1079 else if (c2 == ctype_bool)
1080 {
1081 llassert (ib == ctype_unknown);
1082 ib = c;
1083 }
1084 else if (c2 == ctype_float)
1085 {
1086 llassert (ifl == ctype_unknown);
1087 ifl = c;
1088 }
1089 else if (c2 == CTP_VOID)
1090 {
1091 llassert (iv == ctype_unknown);
1092 iv = c;
1093 }
1094 else
1095 {
1096 /* not special */
1097 }
1098 }
1099 else if (c1 == ib && ib != ctype_unknown)
1100 {
1101 if (c2 == ctype_float)
1102 {
1103 llassert (ibf == ctype_unknown);
1104 ibf = c;
1105 }
1106 else if (c2 == ctype_char)
1107 {
1108 llassert (ibc == ctype_unknown);
1109 ibc = c;
1110 }
1111 else
1112 {
1113 /* not special */
1114 }
1115 }
1116 else if (c1 == iv)
1117 {
1118 if (c2 == ctype_bool)
1119 {
1120 llassert (ivb == ctype_unknown);
1121 ivb = c;
1122 }
1123 else if (c2 == ctype_float)
1124 {
1125 llassert (ivf == ctype_unknown);
1126 ivf = c;
1127 }
1128 else
1129 {
1130 /* not special */
1131 }
1132 }
1133 else if (c1 == ivf)
1134 {
1135 if (c2 == ctype_bool)
1136 {
1137 llassert (ivbf == ctype_unknown);
1138 ivbf = c;
1139 }
1140 }
1141 else if (c1 == ivb)
1142 {
1143 if (c2 == ctype_float)
1144 {
1145 llassert (ivbf == ctype_unknown);
1146 ivbf = c;
1147 }
1148 }
1149 else if (c1 == ctype_char)
1150 {
1151 if (c2 == ctype_uchar)
1152 {
1153 llassert (cuc == ctype_unknown);
1154
1155 cuc = c;
1156 }
1157 }
1158 else
1159 {
1160 /* not special */
1161 }
1162}
1163
1164ctype
1165ctype_makeConj (ctype c1, ctype c2)
1166{
1167 /* no: can have unsigned long @alt long@: llassert (c1 != c2); */
1168
1169 DPRINTF (("Make conj: %s / %s", ctype_unparse (c1), ctype_unparse (c2)));
1170
28bf4b0b 1171 if (ctype_isUnknown (c1))
616915dd 1172 {
28bf4b0b 1173 return c2;
1174 }
1175 else if (ctype_isUnknown (c2))
1176 {
1177 return c1;
1178 }
1179 else if (ctype_isFunction (c1) && !ctype_isFunction (c2))
1180 {
1181 ctype ret = ctype_makeConj (ctype_getReturnType (c1), c2);
616915dd 1182 return ctype_makeFunction (ret, uentryList_copy (ctype_getParams (c1)));
1183 }
1184 else if (ctype_isFunction (c2) && !ctype_isFunction (c1))
1185 {
28bf4b0b 1186 ctype ret = ctype_makeConj (c1, ctype_getReturnType (c2));
616915dd 1187 return ctype_makeFunction (ret, uentryList_copy (ctype_getParams (c2)));
1188 }
1189 else
1190 {
1191 if (ctype_isManifestBool (c1))
1192 {
1193 c1 = ctype_bool;
1194 }
1195
1196 if (ctype_isManifestBool (c2))
1197 {
1198 c2 = ctype_bool;
1199 }
1200
1201 if (ctbase_isVoidPointer (ctype_getCtbaseSafe (c1)))
1202 {
1203 c1 = ctype_voidPointer;
1204 }
1205
1206 if (ctbase_isVoidPointer (ctype_getCtbaseSafe (c2)))
1207 {
1208 c2 = ctype_voidPointer;
1209 }
1210
1211 /*
1212 ** Ouch, can't do this. unsigned, etc. modifiers might
1213 ** apply to wrong type!
1214 **
1215 ** if (c2 == ctype_int && c1 != ctype_int)
1216 ** {
1217 ** ctype tmp;
1218 **
1219 ** tmp = c1;
1220 ** c1 = c2;
1221 ** c2 = tmp;
1222 ** }
1223 **
1224 */
1225
1226 if (c1 == ctype_int)
1227 {
1228 if (c2 == ctype_char)
1229 {
1230 if (ic == ctype_unknown)
1231 {
1232 ic = cttable_addComplex (ctbase_makeConj (ctype_int, ctype_char, FALSE));
1233 }
1234
1235 return ic;
1236 }
1237 else if (c2 == ctype_bool)
1238 {
1239 if (ib == ctype_unknown)
1240 {
1241 ib = cttable_addComplex
1242 (ctbase_makeConj (ctype_int, ctype_bool, FALSE));
1243 }
1244
1245 return ib;
1246 }
1247 else if (c2 == ctype_float)
1248 {
1249 if (ifl == ctype_unknown)
1250 {
1251 ifl = cttable_addComplex (ctbase_makeConj (ctype_int, ctype_float, FALSE));
1252 }
1253
1254 return ifl;
1255 }
1256 else
1257 {
1258 if (c2 == ctype_voidPointer)
1259 {
1260 if (iv == ctype_unknown)
1261 {
1262 iv = cttable_addComplex
1263 (ctbase_makeConj (ctype_int,
1264 ctype_voidPointer,
1265 FALSE));
1266 }
1267
1268 return iv;
1269 }
1270 }
1271 }
1272 else if (c1 == ib && ib != ctype_unknown)
1273 {
1274 if (c2 == ctype_float)
1275 {
1276 if (ibf == ctype_unknown)
1277 {
1278 ibf = cttable_addComplex (ctbase_makeConj (ib, ctype_float, FALSE));
1279 }
1280
1281 return ibf;
1282 }
1283 else if (c2 == ctype_char)
1284 {
1285 if (ibc == ctype_unknown)
1286 {
1287 ibc = cttable_addComplex (ctbase_makeConj (ib, ctype_char, FALSE));
1288 }
1289
1290 return ibc;
1291 }
1292 else
1293 {
1294 ;
1295 }
1296 }
1297 else if (c1 == iv)
1298 {
1299 if (c2 == ctype_bool)
1300 {
1301 if (ivb == ctype_unknown)
1302 {
1303 ivb = cttable_addComplex (ctbase_makeConj (c1, c2, FALSE));
1304 }
1305
1306 return ivb;
1307 }
1308 else if (c2 == ctype_float)
1309 {
1310 if (ivf == ctype_unknown)
1311 {
1312 ivf = cttable_addComplex (ctbase_makeConj (c1, c2, FALSE));
1313 }
1314
1315 return ivf;
1316 }
1317 else
1318 {
1319 ;
1320 }
1321 }
1322 else if (c1 == ivf)
1323 {
1324 if (c2 == ctype_bool)
1325 {
1326 if (ivbf == ctype_unknown)
1327 {
1328 ivbf = cttable_addComplex (ctbase_makeConj (c1, c2, FALSE));
1329 }
1330
1331 return ivbf;
1332 }
1333 }
1334 else if (c1 == ivb)
1335 {
1336 if (c2 == ctype_float)
1337 {
1338 if (ivbf == ctype_unknown)
1339 {
1340 ivbf = cttable_addComplex (ctbase_makeConj (c1, c2, FALSE));
1341 }
1342
1343 return ivbf;
1344 }
1345 }
1346 else if (c1 == ctype_char)
1347 {
1348 if (c2 == ctype_uchar)
1349 {
1350 if (cuc == ctype_unknown)
1351 {
1352 cuc = cttable_addComplex (ctbase_makeConj (c1, c2, FALSE));
1353 }
1354
1355 return cuc;
1356 }
1357 }
1358 else
1359 {
1360 ;
1361 }
1362
1363
1364 return (cttable_addComplex (ctbase_makeConj (c1, c2, FALSE)));
1365 }
1366}
1367
1368
1369bool
1370ctype_isConj (ctype c)
1371{
1372 return (ctype_isComplex (c) && ctbase_isConj (ctype_getCtbase (c)));
1373}
1374
1375static ctype
1376ctype_getConjA (ctype c)
1377{
1378 if (!ctype_isConj (c))
1379 llbuglit ("ctype_getConjA: not a conj");
1380 return (ctbase_getConjA (ctype_getCtbaseSafe (c)));
1381}
1382
1383static ctype
1384ctype_getConjB (ctype c)
1385{
1386 if (!ctype_isConj (c))
1387 llbuglit ("ctype_getConjB: not a conj");
1388 return (ctbase_getConjB (ctype_getCtbaseSafe (c)));
1389}
1390
1391static bool
1392ctype_isExplicitConj (ctype c)
1393{
1394 return (ctype_isConj (c) && ctbase_isExplicitConj (ctype_getCtbaseSafe (c)));
1395}
1396
1397/** << need to fix resolveConj >> **/
1398
1399/*
1400** structs and unions
1401*/
1402
1403ctype
1404ctype_createStruct (/*@only@*/ cstring n, /*@only@*/ uentryList f)
1405{
1406 ctype ct;
1407
1408 DPRINTF (("Creating a struct: %s / %s",
1409 n, uentryList_unparse (f)));
1410
1411 ct = cttable_addComplex (ctbase_createStruct (n, f));
1412 DPRINTF (("ct: %s", ctype_unparse (ct)));
1413 return (ct);
1414}
1415
1416uentryList
1417ctype_getFields (ctype c)
1418{
1419 return (ctbase_getuentryList (ctype_getCtbaseSafe (c)));
1420}
1421
1422ctype
1423ctype_createUnion (/*@only@*/ cstring n, /*@only@*/ uentryList f)
1424{
1425 ctype ret;
1426
1427 ret = cttable_addComplex (ctbase_createUnion (n, f));
1428 return ret;
1429}
1430
1431/*
1432** matching
1433**
1434** if ctype's are same, definite match.
1435** else, need to call ctbase_match.
1436**
1437** if necessary context can memoize matches
1438*/
1439
1440static bool
1441 quickMatch (ctype c1, ctype c2)
1442{
1443 if (c1 == c2)
1444 return TRUE;
1445
1446 return FALSE;
1447}
1448
1449bool
1450ctype_genMatch (ctype c1, ctype c2, bool force, bool arg, bool def, bool deep)
1451{
1452 bool match;
1453
1454 DPRINTF (("Gen match: %s / %s arg: %s", ctype_unparse (c1), ctype_unparse (c2), bool_unparse (arg)));
1455
1456 if (quickMatch (c1, c2))
1457 {
1458 return TRUE;
1459 }
1460
1461 if (ctype_isElips (c1) || ctype_isElips (c2))
1462 {
1463 return FALSE;
1464 }
1465 else
1466 {
1467 match = ctbase_genMatch (ctype_getCtbase (c1), ctype_getCtbase (c2), force, arg, def, deep);
1468 return (match);
1469 }
1470}
1471
1472bool
1473ctype_sameName (ctype c1, ctype c2)
1474{
1475 if (quickMatch (c1, c2))
1476 return TRUE;
1477 else
1478 return (cstring_equal (ctype_unparse (c1), ctype_unparse (c2)));
1479}
1480
1481bool
1482ctype_almostEqual (ctype c1, ctype c2)
1483{
1484 if (ctype_equal (c1, c2))
1485 {
1486 return TRUE;
1487 }
1488 else
1489 {
28bf4b0b 1490 if (ctype_isUnknown (c1))
1491 {
1492 return ctype_isUnknown (c2);
1493 }
1494 else if (ctype_isUnknown (c2))
1495 {
1496 return FALSE;
1497 }
1498 else
1499 {
1500 return (ctbase_almostEqual (ctype_getCtbase (c1), ctype_getCtbase (c2)));
1501 }
616915dd 1502 }
1503}
1504
1505bool
1506ctype_matchDef (ctype c1, ctype c2)
1507{
1508 DPRINTF (("Match def: %s / %s", ctype_unparse (c1), ctype_unparse (c2)));
1509
1510 if (quickMatch (c1, c2))
1511 return TRUE;
1512
1513 if (ctype_isElips (c1))
1514 return (ctype_isElips (c2) || ctype_isUnknown (c2));
1515
1516 if (ctype_isElips (c2))
28bf4b0b 1517 {
1518 return (ctype_isUnknown (c2));
1519 }
616915dd 1520 else
1521 {
1522 bool oldrelax = context_getFlag (FLG_RELAXQUALS);
1523 bool res;
1524
1525 context_setFlagTemp (FLG_RELAXQUALS, FALSE);
1526 res = ctbase_matchDef (ctype_getCtbase (c1), ctype_getCtbase (c2));
1527 context_setFlagTemp (FLG_RELAXQUALS, oldrelax);
1528 return res;
1529 }
1530}
1531
1532bool ctype_match (ctype c1, ctype c2)
1533{
1534 if (quickMatch (c1, c2))
1535 return TRUE;
1536
1537 if (ctype_isElips (c1))
1538 return (ctype_isElips (c2) || ctype_isUnknown (c2));
1539
1540 if (ctype_isElips (c2))
1541 return (ctype_isUnknown (c2));
1542
1543 return (ctbase_match (ctype_getCtbase (c1), ctype_getCtbase (c2)));
1544}
1545
1546bool
1547ctype_forceMatch (ctype c1, ctype c2)
1548{
1549 if (quickMatch (c1, c2))
1550 return TRUE;
1551
1552 if (ctype_isElips (c1))
1553 return (ctype_isElips (c2));
1554
1555 if (ctype_isElips (c2))
1556 return FALSE;
1557
1558 /*@-modobserver@*/
1559 /* The call forceMatch may modify the observer params, but, we don't care. */
1560 return (ctbase_forceMatch (ctype_getCtbase (c1), ctype_getCtbase (c2)));
1561 /*@=modobserver@*/
1562}
1563
1564bool
1565ctype_matchArg (ctype c1, ctype c2)
1566{
1567 if (quickMatch (c1, c2))
1568 {
1569 return TRUE;
1570 }
1571 else
1572 {
1573 return (ctbase_matchArg (ctype_getCtbase (c1), ctype_getCtbase (c2)));
1574 }
1575}
1576
1577/*
1578** simple ctype_is operations.
1579** DO NOT use real type of c, only direct type.
1580*/
1581
1582/*
1583** ctype_isVoidPointer
1584**
1585** void *
1586*/
1587
1588bool
1589ctype_isVoidPointer (ctype c)
1590{
1591 if (ctype_isComplex (c))
1592 {
1593 return ctbase_isVoidPointer (ctype_getCtbaseSafe (c));
1594 }
1595 if (ctype_isConj (c))
1596 {
1597 return (ctype_isVoidPointer (ctype_getConjA (c)) ||
1598 ctype_isVoidPointer (ctype_getConjB (c)));
1599 }
1600 else
1601 {
1602 return (c == ctype_voidPointer
1603 || (ctype_isRealPointer (c)
1604 && ctype_isVoid (ctype_baseArrayPtr (c))));
1605 }
1606}
1607
1608/*
1609** ctype_isPointer
1610**
1611** true for C and LCL pointers
1612*/
1613
1614bool
1615ctype_isPointer (ctype c)
1616{
1617 if (ctype_isElips (c)) return FALSE;
1618
1619 if (ctype_isComplex (c))
1620 {
1621 ctbase ctb = ctype_getCtbaseSafe (c);
1622 bool res = ctbase_isPointer (ctb);
1623
1624 return res;
1625 }
1626 else
1627 {
1628 bool res = ctentry_isPointer (ctype_getCtentry (c));
1629
1630 return res;
1631 }
1632}
1633
1634/*
1635** ctype_isArray
1636**
1637** true for C and LCL array's
1638*/
1639
1640bool
1641ctype_isArray (ctype c)
1642{
1643 if (ctype_isElips (c)) return FALSE;
1644
1645 if (ctype_isComplex (c))
1646 return (ctbase_isEitherArray (ctype_getCtbaseSafe (c)));
1647 else
1648 return (ctentry_isArray (ctype_getCtentry (c)));
1649}
1650
1651bool ctype_isIncompleteArray (ctype c)
1652{
1653 return (ctype_isArray (c) && !ctype_isFixedArray (c));
1654}
1655
1656bool ctype_isFixedArray (ctype c)
1657{
1658 if (ctype_isElips (c)) return FALSE;
1659
1660 return (ctbase_isFixedArray (ctype_getCtbaseSafe (c)));
1661}
1662
1663bool
1664ctype_isArrayPtr (ctype c)
1665{
1666 return ((ctype_isArray (c)) || (ctype_isPointer (c)));
1667}
1668
1669typeId
1670ctype_typeId (ctype c)
1671{
1672 return (ctbase_typeId (ctype_getCtbase (c)));
1673}
1674
1675cstring
1676ctype_unparseDeclaration (ctype c, /*@only@*/ cstring name)
1677{
1678 llassert (!(ctype_isElips (c) || ctype_isMissingParamsMarker (c)));
28bf4b0b 1679
1680 if (ctype_isUnknown (c))
1681 {
1682 return message ("? %q", name);
1683 }
1684 else
1685 {
1686 return (ctbase_unparseDeclaration (ctype_getCtbase (c), name));
1687 }
616915dd 1688}
1689
1690cstring
1691ctype_unparse (ctype c)
1692{
1693 if (ctype_isElips (c))
1694 {
1695 return cstring_makeLiteralTemp ("...");
1696 }
1697 else if (ctype_isMissingParamsMarker (c))
1698 {
1699 return cstring_makeLiteralTemp ("-");
1700 }
28bf4b0b 1701 else if (ctype_isUnknown (c))
1702 {
1703 return cstring_makeLiteralTemp ("?");
1704 }
616915dd 1705 else
1706 {
1707 /*@-modobserver@*/
1708 return (ctentry_doUnparse (ctype_getCtentry (c)));
1709 /*@=modobserver@*/
1710 }
1711}
1712
1713cstring
1714ctype_unparseSafe (ctype c)
1715{
1716 if (ctype_isElips (c))
1717 {
1718 return cstring_makeLiteralTemp ("...");
1719 }
1720 else if (ctype_isMissingParamsMarker (c))
1721 {
1722 return cstring_makeLiteralTemp ("-");
1723 }
1724 else
1725 {
1726 cstring ret;
1727
1728 if /*@+enumint@*/ (c >= CTK_PLAIN && c < cttab.size) /*@=enumint@*/
1729 {
1730 ctentry cte = ctype_getCtentry (c);
1731
1732 if (cstring_isDefined (cte->unparse))
1733 {
1734 return (cte->unparse);
1735 }
1736 }
1737
1738 ret = message ("[%d]", (int) c);
1739 cstring_markOwned (ret);
1740 return ret;
1741 }
1742}
1743
1744cstring
1745ctype_unparseDeep (ctype c)
1746{
1747 if (ctype_isElips (c))
1748 {
1749 return cstring_makeLiteralTemp ("...");
1750 }
1751 if (ctype_isMissingParamsMarker (c))
1752 {
1753 return cstring_makeLiteralTemp ("-");
1754 }
1755
1756 return (ctentry_doUnparseDeep (ctype_getCtentry (c)));
1757}
1758
1759ctype
1760ctype_undump (char **c)
1761{
28bf4b0b 1762 return ((ctype) reader_getInt (c)); /* check its valid? */
616915dd 1763}
1764
1765cstring
1766ctype_dump (ctype c)
1767{
1768 DPRINTF (("Ctype dump: %s", ctype_unparse (c)));
1769
1770 if (c < 0)
1771 {
1772 /* Handle invalid types in a kludgey way. */
1773 return (message ("0"));
1774 }
1775
1776 if (ctype_isUA (c))
1777 {
1778 cstring tname = usymtab_getTypeEntryName
1779 (usymtab_convertId (ctype_typeId (c)));
1780
1781 if (cstring_equal (tname, context_getBoolName ()))
1782 {
1783 cstring_free (tname);
1784 return (message ("%d", ctype_bool));
1785 }
1786
1787 cstring_free (tname);
1788 }
1789
1790 DPRINTF (("Returning: %d", c));
1791 return (message ("%d", c));
1792}
1793
1794ctype
1795ctype_getBaseType (ctype c)
1796{
1797 ctentry cte = ctype_getCtentry (c);
1798
1799 switch (ctentry_getKind (cte))
1800 {
1801 case CTK_UNKNOWN:
616915dd 1802 case CTK_INVALID:
616915dd 1803 case CTK_PLAIN:
1804 return c;
1805 case CTK_PTR:
1806 case CTK_ARRAY:
1807 return (ctype_getBaseType (ctype_baseArrayPtr (c)));
1808 case CTK_COMPLEX:
1809 {
1810 ctbase ctb = cte->ctbase;
1811
1812 if (ctbase_isDefined (ctb))
1813 {
28bf4b0b 1814 /*@access ctbase@*/
616915dd 1815 switch (ctb->type)
1816 {
1817 case CT_UNKNOWN:
1818 case CT_PRIM:
1819 case CT_USER:
1820 case CT_ENUM:
1821 case CT_ENUMLIST:
1822 case CT_BOOL:
1823 case CT_ABST:
1824 case CT_FCN:
1825 case CT_STRUCT:
1826 case CT_UNION:
1827 case CT_EXPFCN:
1828 return c;
1829 case CT_PTR:
1830 case CT_ARRAY:
1831 return (ctype_getBaseType (ctb->contents.base));
1832 case CT_FIXEDARRAY:
1833 return (ctype_getBaseType (ctb->contents.farray->base));
1834 case CT_CONJ: /* base type of A conj branch? */
1835 return (ctype_getBaseType (ctb->contents.conj->a));
1836 }
28bf4b0b 1837 /*@noaccess ctbase@*/
616915dd 1838 }
1839 else
1840 {
1841 return c;
1842 }
1843 }
1844 default:
1845 llbuglit ("ctype_newBase: bad case");
1846 }
1847 llcontbuglit ("ctype_getBaseType: unreachable code");
1848 return ((ctype)NULL);
1849}
1850
1851ctype
1852ctype_adjustPointers (int np, ctype c)
1853{
1854
1855 if (ctype_isFunction (c))
1856 {
1857 c = ctype_makeParamsFunction
28bf4b0b 1858 (ctype_adjustPointers (np, ctype_getReturnType (c)),
616915dd 1859 uentryList_copy (ctype_argsFunction (c)));
1860 }
1861 else
1862 {
1863 /* fix this should not use getBaseType ??? */
1864 ctype cb = ctype_getBaseType (c);
1865
1866 while (np > 0)
1867 {
1868 cb = ctype_makePointer (cb);
1869 np--;
1870 }
1871 c = ctype_newBase (c, cb);
1872 }
1873
1874 return (c);
1875}
1876
1877
1878enumNameList
1879ctype_elist (ctype c)
1880{
1881 return (ctbase_elist (ctype_getCtbase (c)));
1882}
1883
1884bool
1885ctype_isFirstVoid (ctype c)
1886{
1887 return (c == CTX_VOID || (ctype_isConj (c) && ctype_isFirstVoid (ctype_getConjA (c))));
1888}
1889
1890ctype
1891ctype_createEnum (/*@keep@*/ cstring tag, /*@keep@*/ enumNameList el)
1892{
1893 return (cttable_addComplex (ctbase_createEnum (tag, el)));
1894}
1895
1896bool
1897ctype_isEnum (ctype c)
1898{
1899 return (ctype_isComplex (c) && ctbase_isEnum (ctype_getCtbase (c)));
1900}
1901
1902cstring
1903ctype_enumTag (ctype c)
1904{
1905 llassert (ctype_isEnum (c));
1906
1907 return (ctbase_enumTag (ctype_getCtbaseSafe (c)));
1908}
1909
1910bool
1911ctype_isStruct (ctype c)
1912{
1913 return (ctype_isComplex (c) && ctbase_isStruct (ctype_getCtbaseSafe (c)));
1914}
1915
1916bool
1917ctype_isUnion (ctype c)
1918{
1919 return (ctype_isComplex (c) && ctbase_isUnion (ctype_getCtbaseSafe (c)));
1920}
1921
1922ctype
1923ctype_resolveNumerics (ctype c1, ctype c2)
1924{
1925 /*
1926 ** returns longest type of c1 and c2
1927 */
1928
1929 if (c1 == c2) return c1;
1930
1931 c1 = ctype_realType (c1);
1932 c2 = ctype_realType (c2);
1933
1934 if (ctype_isEnum (c1)) c1 = ctype_unknown;
1935 if (ctype_isEnum (c2)) c2 = ctype_int;
1936
1937 if (c1 == ctype_ldouble || c2 == ctype_ldouble) return ctype_ldouble;
28bf4b0b 1938
1939 /* 2001-06-08: This fix provided by Jim Zelenka. */
1940 if (c1 == ctype_llint || c2 == ctype_llint) return ctype_llint;
1941 if (c1 == ctype_ullint || c2 == ctype_ullint) return ctype_ullint;
1942
616915dd 1943 if (c1 == ctype_ulint || c2 == ctype_ulint) return ctype_ulint;
1944 if (c1 == ctype_lint || c2 == ctype_lint) return ctype_lint;
1945 if (c1 == ctype_uint || c2 == ctype_uint) return ctype_uint;
1946 if (c1 == ctype_int || c2 == ctype_int) return ctype_int;
28bf4b0b 1947
1948 /* 2001-06-08: This fix provided by Jim Zelenka. */
1949 if (c1 == ctype_usint || c2 == ctype_usint) return ctype_usint;
1950
616915dd 1951 if (c1 == ctype_sint || c2 == ctype_sint) return ctype_sint;
28bf4b0b 1952
616915dd 1953 if (c1 == ctype_uchar || c2 == ctype_uchar) return ctype_uchar;
1954 if (c1 == ctype_char || c2 == ctype_char) return ctype_char;
1955
1956 if (ctype_isKnown (c1)) return c1;
1957 else return c2;
1958}
1959
1960bool
1961ctype_isStructorUnion (ctype c)
1962{
1963 return (ctype_isStruct (c) || ctype_isUnion (c));
1964}
1965
1966ctype
1967ctype_fixArrayPtr (ctype c)
1968{
1969 if (ctype_isArray (c))
1970 {
1971 return (ctype_makePointer (ctype_baseArrayPtr (c)));
1972 }
1973 else
1974 return c;
1975}
1976
1977/*
1978** createUnnamedStruct/Union
1979**
1980** check if it corresponds to an existing LCL-specified unnamed struct
1981** otherwise, give it a new tag
1982*/
1983
1984ctype
1985ctype_createUnnamedStruct (/*@only@*/ uentryList f)
1986{
1987 ctype ret = usymtab_structFieldsType (f);
1988
28bf4b0b 1989 DPRINTF (("unnamed struct: %s", ctype_unparse (ret)));
1990
616915dd 1991 if (ctype_isDefined (ret))
1992 {
1993 uentryList_free (f);
1994 return ret;
1995 }
1996 else
1997 {
1998 cstring ft = fakeTag ();
1999 ctype ct = ctype_createStruct (cstring_copy (ft), f);
2000 uentry ue = uentry_makeStructTagLoc (ft, ct);
28bf4b0b 2001
2002 DPRINTF (("Unnamed struct: %s", uentry_unparseFull (ue)));
2003 ue = usymtab_supGlobalEntryReturn (ue);
2004 DPRINTF (("After Unnamed struct: %s", uentry_unparseFull (ue)));
2005
616915dd 2006 cstring_free (ft);
2007 return (ct);
2008 }
2009}
2010
2011ctype
2012ctype_createUnnamedUnion (/*@only@*/ uentryList f)
2013{
2014 ctype ret = usymtab_unionFieldsType (f);
2015
2016 if (ctype_isDefined (ret))
2017 {
2018 uentryList_free (f);
2019 return ret;
2020 }
2021 else
2022 {
2023 cstring ft = fakeTag ();
2024 ctype ct = ctype_createUnion (cstring_copy (ft), f);
2025 uentry ue = uentry_makeUnionTagLoc (ft, ct);
2026
2027 usymtab_supGlobalEntry (ue);
2028 cstring_free (ft);
2029 return (ct);
2030 }
2031}
2032
28bf4b0b 2033bool
2034ctype_isUnnamedSU (ctype c)
2035{
2036 if (ctype_isSU (c))
2037 {
2038 return ctbase_isUnnamedSU (ctype_getCtbase (c));
2039 }
2040 else
2041 {
2042 return FALSE;
2043 }
2044}
2045
616915dd 2046ctype
2047ctype_createForwardStruct (cstring n)
2048{
2049 uentry ue = uentry_makeStructTag (n, ctype_unknown, fileloc_undefined);
2050 ctype ct = usymtab_supForwardTypeEntry (ue);
2051
2052 cstring_free (n);
2053 return (ct);
2054}
2055
2056ctype
2057ctype_createForwardUnion (cstring n)
2058{
2059 uentry ue = uentry_makeUnionTag (n, ctype_unknown, fileloc_undefined);
2060 ctype ct = usymtab_supForwardTypeEntry (ue);
2061
2062 cstring_free (n);
2063 return (ct);
2064}
2065
2066ctype
2067ctype_removePointers (ctype c)
2068{
2069 ctype oldc;
2070
28bf4b0b 2071 while (ctype_isKnown (c) && ctype_isArrayPtr (c))
616915dd 2072 {
2073 oldc = c;
2074 c = ctype_baseArrayPtr (c);
2075 llassert (c != oldc);
2076 }
2077
2078 return (c);
2079}
2080
2081bool ctype_isMutable (ctype t)
2082{
2083 if (ctype_isUA (t))
2084 {
2085 return (uentry_isMutableDatatype
2086 (usymtab_getTypeEntry (ctype_typeId (t))));
2087 }
2088 else
2089 {
2090 return (ctype_isPointer (ctype_realType (t)));
28bf4b0b 2091 /*!! || ctype_isStructorUnion (ctype_realType (t))); */
616915dd 2092 }
2093}
2094
2095bool ctype_isRefCounted (ctype t)
2096{
2097 if (ctype_isUA (t))
2098 {
2099 return (uentry_isRefCountedDatatype
2100 (usymtab_getTypeEntry (ctype_typeId (t))));
2101 }
2102
2103 return FALSE;
2104}
2105
2106bool ctype_isVisiblySharable (ctype t)
2107{
2108 if (ctype_isUnknown (t)) return TRUE;
2109
2110 if (ctype_isConj (t))
2111 {
2112 return (ctype_isVisiblySharable (ctype_getConjA (t))
2113 || ctype_isVisiblySharable (ctype_getConjB (t)));
2114 }
2115
2116 if (ctype_isMutable (t))
2117 {
2118 if (ctype_isUA (t))
2119 {
2120 ctype rt = ctype_realType (t);
2121
2122 if (rt == t)
2123 {
2124 return TRUE;
2125 }
2126 else
2127 {
2128 return ctype_isVisiblySharable (rt);
28bf4b0b 2129
616915dd 2130 }
2131 }
2132 else
2133 {
2134 return TRUE;
2135 }
2136 }
2137
2138 return FALSE;
2139}
2140
2141# if 0
2142/* Replaced by ctype_isMutable (more sensible) */
2143bool ctype_canAlias (ctype ct)
2144{
2145 /* can ct refer to memory locations?
2146 ** ==> a pointer or a mutable abstract type
2147 ** arrays?
2148 */
2149
2150 ctype tr = ctype_realType (ct);
2151
2152 return (ctype_isPointer (tr) || ctype_isMutable (ct) || ctype_isStructorUnion (tr));
2153}
2154# endif
2155
2156/*
2157** c1 is the dominant type; c2 is the modifier type
2158**
2159** eg. double + long int => long double
2160*/
2161
2162ctype ctype_combine (ctype dominant, ctype modifier)
2163{
2164 DPRINTF (("Combine: %s + %s",
2165 ctype_unparse (dominant),
2166 ctype_unparse (modifier)));
2167
2168 if (ctype_isConj (dominant))
2169 {
2170 ctype res;
2171
2172 if (ctype_isExplicitConj (dominant))
2173 {
2174 res = ctype_makeExplicitConj (ctype_combine (ctype_getConjA (dominant),
2175 modifier),
2176 ctype_getConjB (dominant));
2177 }
2178 else
2179 {
2180 res = ctype_makeConj (ctype_combine (ctype_getConjA (dominant),
2181 modifier),
2182 ctype_getConjB (dominant));
2183 }
2184
2185 return res;
2186 }
2187
2188 if (ctype_isUnknown (modifier))
2189 {
2190 return dominant;
2191 }
2192 else if (ctype_isUnknown (dominant))
2193 {
2194 return modifier;
2195 }
2196 else
2197 {
2198 if (ctype_isEnum (dominant)) dominant = ctype_int;
2199 if (ctype_isEnum (modifier)) modifier = ctype_int;
2200
2201 if (modifier == ctype_uint)
2202 {
2203 if (dominant == ctype_int) return ctype_uint;
2204 if (dominant == ctype_lint) return ctype_ulint;
2205 if (dominant == ctype_sint) return ctype_usint;
2206 if (dominant == ctype_char) return ctype_uchar;
2207
2208 /* evs 2000-07-28: added this line */
2209 if (dominant == ctype_llint) return ctype_ullint;
2210
2211 if ((dominant == ctype_uint) || dominant == ctype_uchar)
2212 {
2213 voptgenerror (FLG_DUPLICATEQUALS,
2214 message ("Duplicate unsigned qualifier"),
2215 g_currentloc);
2216
2217 return ctype_uint;
2218 }
2219 else
2220 {
2221 voptgenerror (FLG_DUPLICATEQUALS,
2222 message ("Type qualifier unsigned used with %s",
2223 ctype_unparse (dominant)),
2224 g_currentloc);
2225
2226 return dominant;
2227 }
2228 }
2229 else if (modifier == ctype_llint)
2230 {
2231 if (dominant == ctype_int)
2232 {
2233 return ctype_llint;
2234 }
2235
2236 voptgenerror (FLG_DUPLICATEQUALS,
2237 message ("Duplicate long qualifier on non-int"),
2238 g_currentloc);
2239 }
2240 else if (modifier == ctype_lint)
2241 {
2242 if (dominant == ctype_int) return ctype_lint;
2243 if (dominant == ctype_uint) return ctype_ulint;
2244 if (dominant == ctype_double) return ctype_ldouble;
2245
2246 if (dominant == ctype_lint || dominant == ctype_ulint
2247 || dominant == ctype_sint || dominant == ctype_usint
2248 || dominant == ctype_ldouble)
2249 {
2250 if (dominant == ctype_lint)
2251 {
2252 /* long long not supported by ANSI */
2253 return ctype_llint;
2254 }
2255
28bf4b0b 2256 /* ++jimz */
2257 if (dominant == ctype_ulint)
2258 {
2259 /* unsigned long long not supported by ANSI */
2260 return ctype_ullint;
2261 }
2262 /* ==jimz */
2263
616915dd 2264 if (dominant == ctype_sint || dominant == ctype_usint)
2265 {
2266 if (!context_getFlag (FLG_IGNOREQUALS))
2267 {
2268 llerrorlit (FLG_SYNTAX,
2269 "Contradictory long and short type qualifiers");
2270 }
2271 }
2272 else
2273 {
2274 voptgenerror (FLG_DUPLICATEQUALS,
2275 message ("Duplicate long qualifier"),
2276 g_currentloc);
2277 }
2278
2279 return ctype_lint;
2280 }
2281 }
2282 else if (modifier == ctype_sint)
2283 {
2284 if (dominant == ctype_int) return ctype_sint;
2285 if (dominant == ctype_uint) return ctype_usint;
2286
2287 if (dominant == ctype_sint || dominant == ctype_usint)
2288 {
2289 voptgenerror (FLG_DUPLICATEQUALS,
2290 message ("Duplicate short qualifier"),
2291 g_currentloc);
2292 return ctype_uint;
2293 }
2294 else if (dominant == ctype_lint)
2295 {
2296 if (!context_getFlag (FLG_IGNOREQUALS))
2297 {
2298 llerrorlit (FLG_SYNTAX,
2299 "Contradictory long and short type qualifiers");
2300 }
2301
2302 return dominant;
2303 }
28bf4b0b 2304/* ++jimz */
2305 else if (dominant == ctype_llint)
2306 {
2307 if (!context_getFlag (FLG_IGNOREQUALS))
2308 {
2309 llerrorlit (FLG_SYNTAX,
2310 "Contradictory long long and short type qualifiers");
2311 }
2312
2313 return dominant;
2314 }
2315/* ==jimz */
616915dd 2316 else
2317 {
2318 if (!context_getFlag (FLG_IGNOREQUALS))
2319 {
2320 llerror (FLG_SYNTAX,
2321 message ("Type qualifier short used with %s",
2322 ctype_unparse (dominant)));
2323 }
2324
2325 return dominant;
2326 }
2327 }
2328 else if (modifier == ctype_ulint)
2329 {
2330 if (dominant == ctype_int) return modifier;
2331
2332 if (dominant == ctype_lint || dominant == ctype_ulint)
2333 {
2334 voptgenerror (FLG_DUPLICATEQUALS,
2335 message ("Duplicate long qualifier"),
2336 g_currentloc);
2337
2338 return modifier;
2339 }
2340
2341 if (dominant == ctype_uint || dominant == ctype_usint)
2342 {
2343 voptgenerror (FLG_DUPLICATEQUALS,
2344 message ("Duplicate unsigned qualifier"),
2345 g_currentloc);
2346
2347 return modifier;
2348 }
2349
2350 if (dominant == ctype_sint || dominant == ctype_usint)
2351 {
2352 if (!context_getFlag (FLG_IGNOREQUALS))
2353 {
2354 llerrorlit (FLG_SYNTAX,
2355 "Contradictory long and short type qualifiers");
2356 }
2357
2358 return dominant;
2359 }
2360
2361 if (!context_getFlag (FLG_IGNOREQUALS))
2362 {
2363 llerror (FLG_SYNTAX,
2364 message ("Type qualifiers unsigned long used with %s",
2365 ctype_unparse (dominant)));
2366 }
2367
2368 return dominant;
2369 }
2370 else if (modifier == ctype_usint)
2371 {
2372 if (dominant == ctype_int) return modifier;
2373
2374 if (dominant == ctype_sint || dominant == ctype_usint)
2375 {
2376 voptgenerror (FLG_DUPLICATEQUALS,
2377 message ("Duplicate short qualifier"),
2378 g_currentloc);
2379 return modifier;
2380 }
2381
2382 if (dominant == ctype_uint)
2383 {
2384 voptgenerror (FLG_DUPLICATEQUALS,
2385 message ("Duplicate unsigned qualifier"),
2386 g_currentloc);
2387
2388 return modifier;
2389 }
2390
2391 if (dominant == ctype_lint || dominant == ctype_ulint
2392 || dominant == ctype_llint)
2393 {
2394 if (!context_getFlag (FLG_IGNOREQUALS))
2395 {
2396 llerrorlit (FLG_SYNTAX,
2397 "Contradictory long and short type qualifiers");
2398 }
2399
2400 return dominant;
2401 }
2402
2403 if (!context_getFlag (FLG_IGNOREQUALS))
2404 {
2405 llerror (FLG_SYNTAX,
2406 message ("Type qualifiers unsigned short used with %s",
2407 ctype_unparse (dominant)));
2408 }
2409
2410 return dominant;
2411 }
2412 else
2413 {
2414 ;
2415 }
2416
2417 return dominant;
2418 }
2419}
2420
2421ctype ctype_resolve (ctype c)
2422{
2423 if (ctype_isUnknown (c)) return ctype_int;
2424 return c;
2425}
2426
2427ctype ctype_fromQual (qual q)
2428{
2429 if (qual_isSigned (q)) return ctype_int;
2430 if (qual_isUnsigned (q)) return ctype_uint;
2431 if (qual_isLong (q)) return ctype_lint;
2432 if (qual_isShort (q)) return ctype_sint;
2433
2434 llcontbug (message ("ctype_fromQual: invalid qualifier: %s", qual_unparse (q)));
2435 return ctype_unknown;
2436}
2437
2438bool
2439ctype_isAnyFloat (ctype c)
2440{
2441 return (cprim_isAnyReal (ctype_toCprim (c)));
2442}
2443
2444bool
2445ctype_isUnsigned (ctype c)
2446{
2447 if (ctype_isConj (c))
2448 return (ctype_isUnsigned (ctype_getConjA (c)) ||
2449 ctype_isUnsigned (ctype_getConjB (c)));
2450
2451 return (c == ctype_uint || c == ctype_uchar
2452 || c == ctype_usint || c == ctype_ulint
28bf4b0b 2453 || c == ctype_ullint
616915dd 2454 || c == ctype_unsignedintegral);
2455}
2456
28bf4b0b 2457/* ++jimz */
2458static bool
2459ctype_isLongLong (ctype c)
2460{
2461 if (ctype_isConj (c))
2462 return (ctype_isLongLong (ctype_getConjA (c)) ||
2463 ctype_isLongLong (ctype_getConjB (c)));
2464
2465 return (c == ctype_llint || c == ctype_ullint);
2466}
2467/* ==jimz */
2468
616915dd 2469static bool
2470ctype_isLong (ctype c)
2471{
2472 if (ctype_isConj (c))
2473 return (ctype_isLong (ctype_getConjA (c)) ||
2474 ctype_isLong (ctype_getConjB (c)));
2475
2476 return (c == ctype_lint || c == ctype_ulint);
2477}
2478
2479static bool
2480ctype_isShort (ctype c)
2481{
2482 if (ctype_isConj (c))
2483 return (ctype_isShort (ctype_getConjA (c)) ||
2484 ctype_isShort (ctype_getConjB (c)));
2485
2486 return (c == ctype_sint || c == ctype_usint);
2487}
2488
2489bool
2490ctype_isStackAllocated (ctype c)
2491{
2492 ctype ct = ctype_realType (c);
2493
2494 if (ctype_isConj (ct))
2495 return (ctype_isStackAllocated (ctype_getConjA (ct)) ||
2496 ctype_isStackAllocated (ctype_getConjB (ct)));
2497
2498 return (ctype_isArray (c) || ctype_isSU (c));
2499}
2500
2501static bool ctype_isMoreUnsigned (ctype c1, ctype c2)
2502{
2503 return (ctype_isUnsigned (c1) && !ctype_isUnsigned (c2));
2504}
2505
2506static bool ctype_isLonger (ctype c1, ctype c2)
2507{
28bf4b0b 2508 /* 2001-06-10: Fix for long long's provided by Jim Zelenka */
616915dd 2509 return ((ctype_isDouble (c1) && !ctype_isDouble (c2))
28bf4b0b 2510 || (ctype_isLongLong (c1) && !ctype_isLongLong (c2))
2511 || (ctype_isLong (c1)
2512 && (!ctype_isLong (c2)) && (!ctype_isLongLong (c2)))
616915dd 2513 || (ctype_isShort (c2) && !ctype_isShort (c1)));
2514}
2515
2516ctype
2517ctype_widest (ctype c1, ctype c2)
2518{
28bf4b0b 2519 if (ctype_isMoreUnsigned (c2, c1) || ctype_isLonger (c2, c1))
616915dd 2520 {
2521 return c2;
2522 }
2523 else
2524 {
2525 return c1;
2526 }
2527}
2528
28bf4b0b 2529static /*@observer@*/ ctbase ctype_getCtbase (ctype c)
2530{
2531 /*@+enumint@*/
2532 if (c >= 0 && c < cttab.size)
2533 {
2534 return (cttab.entries[c]->ctbase);
2535 }
2536 else
2537 {
2538 if (c == ctype_unknown)
2539 llbuglit ("ctype_getCtbase: ctype unknown");
2540 if (c == ctype_undefined)
2541 llbuglit ("ctype_getCtbase: ctype undefined");
2542 if (c == ctype_dne)
2543 llbuglit ("ctype_getCtbase: ctype dne");
2544 if (c == ctype_elipsMarker)
2545 llbuglit ("ctype_getCtbase: elips marker");
2546
2547 llfatalbug (message ("ctype_getCtbase: ctype out of range: %d", c));
2548 BADEXIT;
2549 }
2550
2551 /*@=enumint@*/
2552}
2553
2554static /*@notnull@*/ /*@observer@*/ ctbase
2555ctype_getCtbaseSafe (ctype c)
2556{
2557 ctbase res = ctype_getCtbase (c);
2558
2559 llassert (ctbase_isDefined (res));
2560 return res;
2561}
2562
2563/*
2564** ctentry
2565*/
2566
2567static ctentry
2568ctype_getCtentry (ctype c)
2569{
2570 static /*@only@*/ ctentry errorEntry = NULL;
2571
2572 if (cttab.size == 0)
2573 {
2574 if (errorEntry == NULL)
2575 {
2576 errorEntry = ctentry_makeNew (CTK_UNKNOWN, ctbase_undefined);
2577 }
2578
2579 return errorEntry;
2580 }
2581
2582 /*@+enumint@*/
2583 if (c >= CTK_PLAIN && c < cttab.size)
2584 {
2585 return (cttab.entries[c]);
2586 }
2587 else if (c == CTK_UNKNOWN)
2588 llcontbuglit ("ctype_getCtentry: ctype unknown");
2589 else if (c == CTK_INVALID)
2590 llcontbuglit ("ctype_getCtentry: ctype invalid (ctype_undefined)");
2591 else if (c == CTK_DNE)
2592 llcontbuglit ("ctype_getCtentry: ctype dne");
2593 else if (c == CTK_ELIPS)
2594 llcontbuglit ("ctype_getCtentry: ctype elipsis");
2595 else if (c == CTK_MISSINGPARAMS)
2596 llcontbuglit ("ctype_getCtentry: ctype missing params");
2597 else
2598 llbug (message ("ctype_getCtentry: ctype out of range: %d", c));
2599
2600 return (cttab.entries[ctype_unknown]);
2601 /*@=enumint@*/
2602}
2603
616915dd 2604/*drl 11/28/2000 */
2605/* requires that the type is an fixed array */
2606/* return the size of the array */
2607
2608long int ctype_getArraySize (ctype c)
2609{
28bf4b0b 2610 long int size;
616915dd 2611 ctentry cte = ctype_getCtentry (c);
2612 ctbase ctb;
616915dd 2613
7534721d 2614 llassert (ctype_isFixedArray (c));
2615 llassert ((ctentry_getKind (cte) == CTK_COMPLEX) || (ctentry_getKind(cte) == CTK_ARRAY));
616915dd 2616
7534721d 2617 ctb = cte->ctbase;
28bf4b0b 2618 size = ctbase_getArraySize (ctb);
616915dd 2619
7534721d 2620 DPRINTF ((message ("ctype_getArraySize: got fixed array size of %s / %d ",
2621 ctype_unparse (c),
2622 (int) size)));
28bf4b0b 2623 return size;
616915dd 2624}
28bf4b0b 2625
This page took 0.391618 seconds and 5 git commands to generate.