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