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