]> andersk Git - splint.git/blame - src/ctype.c
Fixed problem with loop guards in loop test effects. New test case
[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 }
393e573f 337 else if (ctype_isArray (c))
338 {
339 ctype cb = ctype_baseArrayPtr (c);
340
341 res = ctype_makeArray (ctype_makeInnerFixedArray (cb, size));
342 }
077d4458 343 else
344 {
345 res = ctype_makeFixedArray (c, size);
346 }
347
393e573f 348 DPRINTF (("Make inner fixed array: %s", ctype_unparse (res)));
349 return res;
350}
351
352ctype ctype_makeInnerArray (ctype c)
353{
354 ctype res;
355
356 DPRINTF (("Make inner array: %s", ctype_unparse (c)));
357
358 if (ctype_isFixedArray (c))
359 {
360 ctype cb = ctype_baseArrayPtr (c);
361 long osize = ctype_getArraySize (c);
362
363 res = ctype_makeFixedArray (ctype_makeInnerArray (cb),
364 osize);
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{
28bf4b0b 493 if (ctype_isUnknown (c))
494 {
495 return ctype_unknown;
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{
28bf4b0b 508 if (ctype_isUnknown (c))
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
28bf4b0b 594 if (ctype_isUnknown (c1))
595 {
596 if (ctype_isUnknown (c2))
597 {
598 return 0;
599 }
600 else
601 {
602 return 1;
603 }
604 }
605
606 if (ctype_isUnknown (c2))
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{
1142 if (ctype_isFunction (c1) && !ctype_isFunction (c2))
1143 {
28bf4b0b 1144 ctype ret = ctype_makeExplicitConj (ctype_getReturnType (c1), c2);
616915dd 1145
1146 return ctype_makeFunction (ret, uentryList_copy (ctype_getParams (c1)));
1147 }
1148 else if (ctype_isFunction (c2) && !ctype_isFunction (c1))
1149 {
28bf4b0b 1150 ctype ret = ctype_makeExplicitConj (c1, ctype_getReturnType (c2));
616915dd 1151
1152 return ctype_makeFunction (ret, uentryList_copy (ctype_getParams (c2)));
1153 }
1154 else
1155 {
1156 return (cttable_addComplex (ctbase_makeConj (c1, c2, TRUE)));
1157 }
1158}
1159
1160static ctype ic = ctype_unknown; /* int | char */
1161static ctype ib = ctype_unknown; /* int | bool */
1162static ctype ifl = ctype_unknown; /* int | float */
1163static ctype ibf = ctype_unknown; /* int | bool | float */
1164static ctype ibc = ctype_unknown; /* int | bool | char */
1165static ctype iv = ctype_unknown; /* int | void * */
1166static ctype ivf = ctype_unknown; /* int | void * | float */
1167static ctype ivb = ctype_unknown; /* int | void * | bool */
1168static ctype ivbf = ctype_unknown; /* int | void * | bool | float */
1169static ctype cuc = ctype_unknown; /* char | unsigned char */
1170
1171static void
1172ctype_recordConj (ctype c)
1173{
1174 ctype c1, c2;
1175
1176 llassert (ctype_isConj (c));
1177
1178 c1 = ctype_getConjA (c);
1179 c2 = ctype_getConjB (c);
1180
1181 /* No, can't swap!
1182 if (c2 == ctype_int && c1 != ctype_int)
1183 {
1184 ctype tmp;
1185
1186 tmp = c1;
1187 c1 = c2;
1188 c2 = tmp;
1189 }
1190 */
1191
1192 if (c1 == ctype_int)
1193 {
1194 if (c2 == ctype_char)
1195 {
1196 llassert (ic == ctype_unknown);
1197 ic = c;
1198 }
1199 else if (c2 == ctype_bool)
1200 {
1201 llassert (ib == ctype_unknown);
1202 ib = c;
1203 }
1204 else if (c2 == ctype_float)
1205 {
1206 llassert (ifl == ctype_unknown);
1207 ifl = c;
1208 }
1209 else if (c2 == CTP_VOID)
1210 {
1211 llassert (iv == ctype_unknown);
1212 iv = c;
1213 }
1214 else
1215 {
1216 /* not special */
1217 }
1218 }
1219 else if (c1 == ib && ib != ctype_unknown)
1220 {
1221 if (c2 == ctype_float)
1222 {
1223 llassert (ibf == ctype_unknown);
1224 ibf = c;
1225 }
1226 else if (c2 == ctype_char)
1227 {
1228 llassert (ibc == ctype_unknown);
1229 ibc = c;
1230 }
1231 else
1232 {
1233 /* not special */
1234 }
1235 }
1236 else if (c1 == iv)
1237 {
1238 if (c2 == ctype_bool)
1239 {
1240 llassert (ivb == ctype_unknown);
1241 ivb = c;
1242 }
1243 else if (c2 == ctype_float)
1244 {
1245 llassert (ivf == ctype_unknown);
1246 ivf = c;
1247 }
1248 else
1249 {
1250 /* not special */
1251 }
1252 }
1253 else if (c1 == ivf)
1254 {
1255 if (c2 == ctype_bool)
1256 {
1257 llassert (ivbf == ctype_unknown);
1258 ivbf = c;
1259 }
1260 }
1261 else if (c1 == ivb)
1262 {
1263 if (c2 == ctype_float)
1264 {
1265 llassert (ivbf == ctype_unknown);
1266 ivbf = c;
1267 }
1268 }
1269 else if (c1 == ctype_char)
1270 {
1271 if (c2 == ctype_uchar)
1272 {
1273 llassert (cuc == ctype_unknown);
1274
1275 cuc = c;
1276 }
1277 }
1278 else
1279 {
1280 /* not special */
1281 }
1282}
1283
1284ctype
1285ctype_makeConj (ctype c1, ctype c2)
1286{
1287 /* no: can have unsigned long @alt long@: llassert (c1 != c2); */
1288
1289 DPRINTF (("Make conj: %s / %s", ctype_unparse (c1), ctype_unparse (c2)));
1290
28bf4b0b 1291 if (ctype_isUnknown (c1))
616915dd 1292 {
28bf4b0b 1293 return c2;
1294 }
1295 else if (ctype_isUnknown (c2))
1296 {
1297 return c1;
1298 }
1299 else if (ctype_isFunction (c1) && !ctype_isFunction (c2))
1300 {
1301 ctype ret = ctype_makeConj (ctype_getReturnType (c1), c2);
616915dd 1302 return ctype_makeFunction (ret, uentryList_copy (ctype_getParams (c1)));
1303 }
1304 else if (ctype_isFunction (c2) && !ctype_isFunction (c1))
1305 {
28bf4b0b 1306 ctype ret = ctype_makeConj (c1, ctype_getReturnType (c2));
616915dd 1307 return ctype_makeFunction (ret, uentryList_copy (ctype_getParams (c2)));
1308 }
1309 else
1310 {
1311 if (ctype_isManifestBool (c1))
1312 {
1313 c1 = ctype_bool;
1314 }
1315
1316 if (ctype_isManifestBool (c2))
1317 {
1318 c2 = ctype_bool;
1319 }
1320
1321 if (ctbase_isVoidPointer (ctype_getCtbaseSafe (c1)))
1322 {
1323 c1 = ctype_voidPointer;
1324 }
1325
1326 if (ctbase_isVoidPointer (ctype_getCtbaseSafe (c2)))
1327 {
1328 c2 = ctype_voidPointer;
1329 }
1330
1331 /*
1332 ** Ouch, can't do this. unsigned, etc. modifiers might
1333 ** apply to wrong type!
1334 **
1335 ** if (c2 == ctype_int && c1 != ctype_int)
1336 ** {
1337 ** ctype tmp;
1338 **
1339 ** tmp = c1;
1340 ** c1 = c2;
1341 ** c2 = tmp;
1342 ** }
1343 **
1344 */
1345
1346 if (c1 == ctype_int)
1347 {
1348 if (c2 == ctype_char)
1349 {
1350 if (ic == ctype_unknown)
1351 {
1352 ic = cttable_addComplex (ctbase_makeConj (ctype_int, ctype_char, FALSE));
1353 }
1354
1355 return ic;
1356 }
1357 else if (c2 == ctype_bool)
1358 {
1359 if (ib == ctype_unknown)
1360 {
1361 ib = cttable_addComplex
1362 (ctbase_makeConj (ctype_int, ctype_bool, FALSE));
1363 }
1364
1365 return ib;
1366 }
1367 else if (c2 == ctype_float)
1368 {
1369 if (ifl == ctype_unknown)
1370 {
1371 ifl = cttable_addComplex (ctbase_makeConj (ctype_int, ctype_float, FALSE));
1372 }
1373
1374 return ifl;
1375 }
1376 else
1377 {
1378 if (c2 == ctype_voidPointer)
1379 {
1380 if (iv == ctype_unknown)
1381 {
1382 iv = cttable_addComplex
bb7c2085 1383 (ctbase_makeConj (ctype_int,
616915dd 1384 ctype_voidPointer,
1385 FALSE));
1386 }
1387
1388 return iv;
1389 }
1390 }
1391 }
1392 else if (c1 == ib && ib != ctype_unknown)
1393 {
1394 if (c2 == ctype_float)
1395 {
1396 if (ibf == ctype_unknown)
1397 {
1398 ibf = cttable_addComplex (ctbase_makeConj (ib, ctype_float, FALSE));
1399 }
1400
1401 return ibf;
1402 }
1403 else if (c2 == ctype_char)
1404 {
1405 if (ibc == ctype_unknown)
1406 {
1407 ibc = cttable_addComplex (ctbase_makeConj (ib, ctype_char, FALSE));
1408 }
1409
1410 return ibc;
1411 }
1412 else
1413 {
1414 ;
1415 }
1416 }
1417 else if (c1 == iv)
1418 {
1419 if (c2 == ctype_bool)
1420 {
1421 if (ivb == ctype_unknown)
1422 {
1423 ivb = cttable_addComplex (ctbase_makeConj (c1, c2, FALSE));
1424 }
1425
1426 return ivb;
1427 }
1428 else if (c2 == ctype_float)
1429 {
1430 if (ivf == ctype_unknown)
1431 {
1432 ivf = cttable_addComplex (ctbase_makeConj (c1, c2, FALSE));
1433 }
1434
1435 return ivf;
1436 }
1437 else
1438 {
1439 ;
1440 }
1441 }
1442 else if (c1 == ivf)
1443 {
1444 if (c2 == ctype_bool)
1445 {
1446 if (ivbf == ctype_unknown)
1447 {
1448 ivbf = cttable_addComplex (ctbase_makeConj (c1, c2, FALSE));
1449 }
1450
1451 return ivbf;
1452 }
1453 }
1454 else if (c1 == ivb)
1455 {
1456 if (c2 == ctype_float)
1457 {
1458 if (ivbf == ctype_unknown)
1459 {
1460 ivbf = cttable_addComplex (ctbase_makeConj (c1, c2, FALSE));
1461 }
1462
1463 return ivbf;
1464 }
1465 }
1466 else if (c1 == ctype_char)
1467 {
1468 if (c2 == ctype_uchar)
1469 {
1470 if (cuc == ctype_unknown)
1471 {
1472 cuc = cttable_addComplex (ctbase_makeConj (c1, c2, FALSE));
1473 }
1474
1475 return cuc;
1476 }
1477 }
1478 else
1479 {
1480 ;
1481 }
1482
1483
1484 return (cttable_addComplex (ctbase_makeConj (c1, c2, FALSE)));
1485 }
1486}
1487
1488
1489bool
1490ctype_isConj (ctype c)
1491{
1492 return (ctype_isComplex (c) && ctbase_isConj (ctype_getCtbase (c)));
1493}
1494
1495static ctype
1496ctype_getConjA (ctype c)
1497{
1498 if (!ctype_isConj (c))
1499 llbuglit ("ctype_getConjA: not a conj");
1500 return (ctbase_getConjA (ctype_getCtbaseSafe (c)));
1501}
1502
1503static ctype
1504ctype_getConjB (ctype c)
1505{
1506 if (!ctype_isConj (c))
1507 llbuglit ("ctype_getConjB: not a conj");
1508 return (ctbase_getConjB (ctype_getCtbaseSafe (c)));
1509}
1510
1511static bool
1512ctype_isExplicitConj (ctype c)
1513{
1514 return (ctype_isConj (c) && ctbase_isExplicitConj (ctype_getCtbaseSafe (c)));
1515}
1516
1517/** << need to fix resolveConj >> **/
1518
1519/*
1520** structs and unions
1521*/
1522
1523ctype
1524ctype_createStruct (/*@only@*/ cstring n, /*@only@*/ uentryList f)
1525{
1526 ctype ct;
1527
1528 DPRINTF (("Creating a struct: %s / %s",
1529 n, uentryList_unparse (f)));
1530
1531 ct = cttable_addComplex (ctbase_createStruct (n, f));
1532 DPRINTF (("ct: %s", ctype_unparse (ct)));
1533 return (ct);
1534}
1535
1536uentryList
1537ctype_getFields (ctype c)
1538{
1539 return (ctbase_getuentryList (ctype_getCtbaseSafe (c)));
1540}
1541
1542ctype
1543ctype_createUnion (/*@only@*/ cstring n, /*@only@*/ uentryList f)
1544{
1545 ctype ret;
1546
1547 ret = cttable_addComplex (ctbase_createUnion (n, f));
1548 return ret;
1549}
1550
1551/*
1552** matching
1553**
1554** if ctype's are same, definite match.
1555** else, need to call ctbase_match.
1556**
1557** if necessary context can memoize matches
1558*/
1559
1560static bool
1561 quickMatch (ctype c1, ctype c2)
1562{
1563 if (c1 == c2)
1564 return TRUE;
1565
1566 return FALSE;
1567}
1568
1569bool
1570ctype_genMatch (ctype c1, ctype c2, bool force, bool arg, bool def, bool deep)
1571{
1572 bool match;
1573
1574 DPRINTF (("Gen match: %s / %s arg: %s", ctype_unparse (c1), ctype_unparse (c2), bool_unparse (arg)));
1575
1576 if (quickMatch (c1, c2))
1577 {
1578 return TRUE;
1579 }
1580
1581 if (ctype_isElips (c1) || ctype_isElips (c2))
1582 {
1583 return FALSE;
1584 }
1585 else
1586 {
1587 match = ctbase_genMatch (ctype_getCtbase (c1), ctype_getCtbase (c2), force, arg, def, deep);
1588 return (match);
1589 }
1590}
1591
1592bool
1593ctype_sameName (ctype c1, ctype c2)
1594{
1595 if (quickMatch (c1, c2))
1596 return TRUE;
1597 else
1598 return (cstring_equal (ctype_unparse (c1), ctype_unparse (c2)));
1599}
1600
1601bool
1602ctype_almostEqual (ctype c1, ctype c2)
1603{
1604 if (ctype_equal (c1, c2))
1605 {
1606 return TRUE;
1607 }
1608 else
1609 {
28bf4b0b 1610 if (ctype_isUnknown (c1))
1611 {
1612 return ctype_isUnknown (c2);
1613 }
1614 else if (ctype_isUnknown (c2))
1615 {
1616 return FALSE;
1617 }
1618 else
1619 {
1620 return (ctbase_almostEqual (ctype_getCtbase (c1), ctype_getCtbase (c2)));
1621 }
616915dd 1622 }
1623}
1624
1625bool
1626ctype_matchDef (ctype c1, ctype c2)
1627{
1628 DPRINTF (("Match def: %s / %s", ctype_unparse (c1), ctype_unparse (c2)));
1629
1630 if (quickMatch (c1, c2))
1631 return TRUE;
1632
1633 if (ctype_isElips (c1))
1634 return (ctype_isElips (c2) || ctype_isUnknown (c2));
1635
1636 if (ctype_isElips (c2))
28bf4b0b 1637 {
1638 return (ctype_isUnknown (c2));
1639 }
616915dd 1640 else
1641 {
1642 bool oldrelax = context_getFlag (FLG_RELAXQUALS);
1643 bool res;
1644
1645 context_setFlagTemp (FLG_RELAXQUALS, FALSE);
1646 res = ctbase_matchDef (ctype_getCtbase (c1), ctype_getCtbase (c2));
1647 context_setFlagTemp (FLG_RELAXQUALS, oldrelax);
1648 return res;
1649 }
1650}
1651
1652bool ctype_match (ctype c1, ctype c2)
1653{
1654 if (quickMatch (c1, c2))
1655 return TRUE;
1656
1657 if (ctype_isElips (c1))
1658 return (ctype_isElips (c2) || ctype_isUnknown (c2));
1659
1660 if (ctype_isElips (c2))
1661 return (ctype_isUnknown (c2));
1662
1663 return (ctbase_match (ctype_getCtbase (c1), ctype_getCtbase (c2)));
1664}
1665
1666bool
1667ctype_forceMatch (ctype c1, ctype c2)
1668{
1669 if (quickMatch (c1, c2))
1670 return TRUE;
1671
1672 if (ctype_isElips (c1))
1673 return (ctype_isElips (c2));
1674
1675 if (ctype_isElips (c2))
1676 return FALSE;
1677
1678 /*@-modobserver@*/
1679 /* The call forceMatch may modify the observer params, but, we don't care. */
1680 return (ctbase_forceMatch (ctype_getCtbase (c1), ctype_getCtbase (c2)));
1681 /*@=modobserver@*/
1682}
1683
1684bool
1685ctype_matchArg (ctype c1, ctype c2)
1686{
1687 if (quickMatch (c1, c2))
1688 {
1689 return TRUE;
1690 }
1691 else
1692 {
1693 return (ctbase_matchArg (ctype_getCtbase (c1), ctype_getCtbase (c2)));
1694 }
1695}
1696
1697/*
1698** simple ctype_is operations.
1699** DO NOT use real type of c, only direct type.
1700*/
1701
1702/*
1703** ctype_isVoidPointer
1704**
1705** void *
1706*/
1707
1708bool
1709ctype_isVoidPointer (ctype c)
1710{
1711 if (ctype_isComplex (c))
1712 {
1713 return ctbase_isVoidPointer (ctype_getCtbaseSafe (c));
1714 }
1715 if (ctype_isConj (c))
1716 {
1717 return (ctype_isVoidPointer (ctype_getConjA (c)) ||
1718 ctype_isVoidPointer (ctype_getConjB (c)));
1719 }
1720 else
1721 {
1722 return (c == ctype_voidPointer
1723 || (ctype_isRealPointer (c)
1724 && ctype_isVoid (ctype_baseArrayPtr (c))));
1725 }
1726}
1727
1728/*
1729** ctype_isPointer
1730**
1731** true for C and LCL pointers
1732*/
1733
1734bool
1735ctype_isPointer (ctype c)
1736{
1737 if (ctype_isElips (c)) return FALSE;
1738
1739 if (ctype_isComplex (c))
1740 {
1741 ctbase ctb = ctype_getCtbaseSafe (c);
1742 bool res = ctbase_isPointer (ctb);
1743
1744 return res;
1745 }
1746 else
1747 {
1748 bool res = ctentry_isPointer (ctype_getCtentry (c));
1749
1750 return res;
1751 }
1752}
1753
1754/*
1755** ctype_isArray
1756**
1757** true for C and LCL array's
1758*/
1759
1760bool
1761ctype_isArray (ctype c)
1762{
1763 if (ctype_isElips (c)) return FALSE;
1764
1765 if (ctype_isComplex (c))
1766 return (ctbase_isEitherArray (ctype_getCtbaseSafe (c)));
1767 else
1768 return (ctentry_isArray (ctype_getCtentry (c)));
1769}
1770
1771bool ctype_isIncompleteArray (ctype c)
1772{
1773 return (ctype_isArray (c) && !ctype_isFixedArray (c));
1774}
1775
616915dd 1776bool
1777ctype_isArrayPtr (ctype c)
1778{
1779 return ((ctype_isArray (c)) || (ctype_isPointer (c)));
1780}
1781
1782typeId
1783ctype_typeId (ctype c)
1784{
1785 return (ctbase_typeId (ctype_getCtbase (c)));
1786}
1787
1788cstring
1789ctype_unparseDeclaration (ctype c, /*@only@*/ cstring name)
1790{
bb7c2085 1791 llassert (! (ctype_isElips (c) || ctype_isMissingParamsMarker (c)));
28bf4b0b 1792
1793 if (ctype_isUnknown (c))
1794 {
1795 return message ("? %q", name);
1796 }
1797 else
1798 {
1799 return (ctbase_unparseDeclaration (ctype_getCtbase (c), name));
1800 }
616915dd 1801}
1802
1803cstring
1804ctype_unparse (ctype c)
1805{
1806 if (ctype_isElips (c))
1807 {
1808 return cstring_makeLiteralTemp ("...");
1809 }
1810 else if (ctype_isMissingParamsMarker (c))
1811 {
1812 return cstring_makeLiteralTemp ("-");
1813 }
28bf4b0b 1814 else if (ctype_isUnknown (c))
1815 {
1816 return cstring_makeLiteralTemp ("?");
1817 }
616915dd 1818 else
1819 {
1820 /*@-modobserver@*/
1821 return (ctentry_doUnparse (ctype_getCtentry (c)));
1822 /*@=modobserver@*/
1823 }
1824}
1825
1826cstring
1827ctype_unparseSafe (ctype c)
1828{
1829 if (ctype_isElips (c))
1830 {
1831 return cstring_makeLiteralTemp ("...");
1832 }
1833 else if (ctype_isMissingParamsMarker (c))
1834 {
1835 return cstring_makeLiteralTemp ("-");
1836 }
1837 else
1838 {
1839 cstring ret;
1840
1841 if /*@+enumint@*/ (c >= CTK_PLAIN && c < cttab.size) /*@=enumint@*/
1842 {
1843 ctentry cte = ctype_getCtentry (c);
1844
1845 if (cstring_isDefined (cte->unparse))
1846 {
1847 return (cte->unparse);
1848 }
1849 }
1850
1851 ret = message ("[%d]", (int) c);
1852 cstring_markOwned (ret);
1853 return ret;
1854 }
1855}
1856
1857cstring
1858ctype_unparseDeep (ctype c)
1859{
1860 if (ctype_isElips (c))
1861 {
1862 return cstring_makeLiteralTemp ("...");
1863 }
1864 if (ctype_isMissingParamsMarker (c))
1865 {
1866 return cstring_makeLiteralTemp ("-");
1867 }
1868
1869 return (ctentry_doUnparseDeep (ctype_getCtentry (c)));
1870}
1871
1872ctype
1873ctype_undump (char **c)
1874{
28bf4b0b 1875 return ((ctype) reader_getInt (c)); /* check its valid? */
616915dd 1876}
1877
1878cstring
1879ctype_dump (ctype c)
1880{
1881 DPRINTF (("Ctype dump: %s", ctype_unparse (c)));
1882
1883 if (c < 0)
1884 {
1885 /* Handle invalid types in a kludgey way. */
1886 return (message ("0"));
1887 }
1888
1889 if (ctype_isUA (c))
1890 {
1891 cstring tname = usymtab_getTypeEntryName
bb7c2085 1892 (usymtab_convertId (ctype_typeId (c)));
616915dd 1893
1894 if (cstring_equal (tname, context_getBoolName ()))
1895 {
1896 cstring_free (tname);
1897 return (message ("%d", ctype_bool));
1898 }
1899
1900 cstring_free (tname);
1901 }
1902
1903 DPRINTF (("Returning: %d", c));
1904 return (message ("%d", c));
1905}
1906
1907ctype
1908ctype_getBaseType (ctype c)
1909{
1910 ctentry cte = ctype_getCtentry (c);
1911
1912 switch (ctentry_getKind (cte))
1913 {
1914 case CTK_UNKNOWN:
616915dd 1915 case CTK_INVALID:
616915dd 1916 case CTK_PLAIN:
1917 return c;
1918 case CTK_PTR:
1919 case CTK_ARRAY:
1920 return (ctype_getBaseType (ctype_baseArrayPtr (c)));
1921 case CTK_COMPLEX:
1922 {
1923 ctbase ctb = cte->ctbase;
1924
1925 if (ctbase_isDefined (ctb))
1926 {
28bf4b0b 1927 /*@access ctbase@*/
616915dd 1928 switch (ctb->type)
1929 {
1930 case CT_UNKNOWN:
1931 case CT_PRIM:
1932 case CT_USER:
1933 case CT_ENUM:
1934 case CT_ENUMLIST:
1935 case CT_BOOL:
1936 case CT_ABST:
1937 case CT_FCN:
1938 case CT_STRUCT:
1939 case CT_UNION:
1940 case CT_EXPFCN:
1941 return c;
1942 case CT_PTR:
1943 case CT_ARRAY:
1944 return (ctype_getBaseType (ctb->contents.base));
1945 case CT_FIXEDARRAY:
1946 return (ctype_getBaseType (ctb->contents.farray->base));
1947 case CT_CONJ: /* base type of A conj branch? */
1948 return (ctype_getBaseType (ctb->contents.conj->a));
1949 }
28bf4b0b 1950 /*@noaccess ctbase@*/
616915dd 1951 }
1952 else
1953 {
1954 return c;
1955 }
1956 }
1957 default:
1958 llbuglit ("ctype_newBase: bad case");
1959 }
1960 llcontbuglit ("ctype_getBaseType: unreachable code");
1961 return ((ctype)NULL);
1962}
1963
1964ctype
1965ctype_adjustPointers (int np, ctype c)
1966{
1967
1968 if (ctype_isFunction (c))
1969 {
1970 c = ctype_makeParamsFunction
bb7c2085 1971 (ctype_adjustPointers (np, ctype_getReturnType (c)),
616915dd 1972 uentryList_copy (ctype_argsFunction (c)));
1973 }
1974 else
1975 {
1976 /* fix this should not use getBaseType ??? */
1977 ctype cb = ctype_getBaseType (c);
1978
1979 while (np > 0)
1980 {
1981 cb = ctype_makePointer (cb);
1982 np--;
1983 }
1984 c = ctype_newBase (c, cb);
1985 }
1986
1987 return (c);
1988}
1989
1990
1991enumNameList
1992ctype_elist (ctype c)
1993{
1994 return (ctbase_elist (ctype_getCtbase (c)));
1995}
1996
1997bool
1998ctype_isFirstVoid (ctype c)
1999{
2000 return (c == CTX_VOID || (ctype_isConj (c) && ctype_isFirstVoid (ctype_getConjA (c))));
2001}
2002
2003ctype
2004ctype_createEnum (/*@keep@*/ cstring tag, /*@keep@*/ enumNameList el)
2005{
2006 return (cttable_addComplex (ctbase_createEnum (tag, el)));
2007}
2008
2009bool
2010ctype_isEnum (ctype c)
2011{
2012 return (ctype_isComplex (c) && ctbase_isEnum (ctype_getCtbase (c)));
2013}
2014
2015cstring
2016ctype_enumTag (ctype c)
2017{
2018 llassert (ctype_isEnum (c));
2019
2020 return (ctbase_enumTag (ctype_getCtbaseSafe (c)));
2021}
2022
2023bool
2024ctype_isStruct (ctype c)
2025{
2026 return (ctype_isComplex (c) && ctbase_isStruct (ctype_getCtbaseSafe (c)));
2027}
2028
2029bool
2030ctype_isUnion (ctype c)
2031{
2032 return (ctype_isComplex (c) && ctbase_isUnion (ctype_getCtbaseSafe (c)));
2033}
2034
2035ctype
2036ctype_resolveNumerics (ctype c1, ctype c2)
2037{
2038 /*
2039 ** returns longest type of c1 and c2
2040 */
2041
2042 if (c1 == c2) return c1;
2043
2044 c1 = ctype_realType (c1);
2045 c2 = ctype_realType (c2);
2046
2047 if (ctype_isEnum (c1)) c1 = ctype_unknown;
2048 if (ctype_isEnum (c2)) c2 = ctype_int;
2049
2050 if (c1 == ctype_ldouble || c2 == ctype_ldouble) return ctype_ldouble;
28bf4b0b 2051
2052 /* 2001-06-08: This fix provided by Jim Zelenka. */
2053 if (c1 == ctype_llint || c2 == ctype_llint) return ctype_llint;
2054 if (c1 == ctype_ullint || c2 == ctype_ullint) return ctype_ullint;
2055
616915dd 2056 if (c1 == ctype_ulint || c2 == ctype_ulint) return ctype_ulint;
2057 if (c1 == ctype_lint || c2 == ctype_lint) return ctype_lint;
2058 if (c1 == ctype_uint || c2 == ctype_uint) return ctype_uint;
2059 if (c1 == ctype_int || c2 == ctype_int) return ctype_int;
28bf4b0b 2060
2061 /* 2001-06-08: This fix provided by Jim Zelenka. */
2062 if (c1 == ctype_usint || c2 == ctype_usint) return ctype_usint;
2063
616915dd 2064 if (c1 == ctype_sint || c2 == ctype_sint) return ctype_sint;
28bf4b0b 2065
616915dd 2066 if (c1 == ctype_uchar || c2 == ctype_uchar) return ctype_uchar;
2067 if (c1 == ctype_char || c2 == ctype_char) return ctype_char;
2068
2069 if (ctype_isKnown (c1)) return c1;
2070 else return c2;
2071}
2072
2073bool
2074ctype_isStructorUnion (ctype c)
2075{
2076 return (ctype_isStruct (c) || ctype_isUnion (c));
2077}
2078
2079ctype
2080ctype_fixArrayPtr (ctype c)
2081{
2082 if (ctype_isArray (c))
2083 {
2084 return (ctype_makePointer (ctype_baseArrayPtr (c)));
2085 }
2086 else
2087 return c;
2088}
2089
2090/*
2091** createUnnamedStruct/Union
2092**
2093** check if it corresponds to an existing LCL-specified unnamed struct
2094** otherwise, give it a new tag
2095*/
2096
2097ctype
2098ctype_createUnnamedStruct (/*@only@*/ uentryList f)
2099{
2100 ctype ret = usymtab_structFieldsType (f);
2101
28bf4b0b 2102 DPRINTF (("unnamed struct: %s", ctype_unparse (ret)));
2103
616915dd 2104 if (ctype_isDefined (ret))
2105 {
2106 uentryList_free (f);
2107 return ret;
2108 }
2109 else
2110 {
2111 cstring ft = fakeTag ();
2112 ctype ct = ctype_createStruct (cstring_copy (ft), f);
2113 uentry ue = uentry_makeStructTagLoc (ft, ct);
28bf4b0b 2114
2115 DPRINTF (("Unnamed struct: %s", uentry_unparseFull (ue)));
2116 ue = usymtab_supGlobalEntryReturn (ue);
2117 DPRINTF (("After Unnamed struct: %s", uentry_unparseFull (ue)));
2118
616915dd 2119 cstring_free (ft);
2120 return (ct);
2121 }
2122}
2123
2124ctype
2125ctype_createUnnamedUnion (/*@only@*/ uentryList f)
2126{
2127 ctype ret = usymtab_unionFieldsType (f);
2128
2129 if (ctype_isDefined (ret))
2130 {
2131 uentryList_free (f);
2132 return ret;
2133 }
2134 else
2135 {
2136 cstring ft = fakeTag ();
2137 ctype ct = ctype_createUnion (cstring_copy (ft), f);
2138 uentry ue = uentry_makeUnionTagLoc (ft, ct);
2139
2140 usymtab_supGlobalEntry (ue);
2141 cstring_free (ft);
2142 return (ct);
2143 }
2144}
2145
28bf4b0b 2146bool
2147ctype_isUnnamedSU (ctype c)
2148{
2149 if (ctype_isSU (c))
2150 {
2151 return ctbase_isUnnamedSU (ctype_getCtbase (c));
2152 }
2153 else
2154 {
2155 return FALSE;
2156 }
2157}
2158
616915dd 2159ctype
2160ctype_createForwardStruct (cstring n)
2161{
2162 uentry ue = uentry_makeStructTag (n, ctype_unknown, fileloc_undefined);
2163 ctype ct = usymtab_supForwardTypeEntry (ue);
2164
2165 cstring_free (n);
2166 return (ct);
2167}
2168
2169ctype
2170ctype_createForwardUnion (cstring n)
2171{
2172 uentry ue = uentry_makeUnionTag (n, ctype_unknown, fileloc_undefined);
2173 ctype ct = usymtab_supForwardTypeEntry (ue);
2174
2175 cstring_free (n);
2176 return (ct);
2177}
2178
2179ctype
2180ctype_removePointers (ctype c)
2181{
2182 ctype oldc;
2183
28bf4b0b 2184 while (ctype_isKnown (c) && ctype_isArrayPtr (c))
616915dd 2185 {
2186 oldc = c;
2187 c = ctype_baseArrayPtr (c);
2188 llassert (c != oldc);
2189 }
2190
2191 return (c);
2192}
2193
2194bool ctype_isMutable (ctype t)
2195{
2196 if (ctype_isUA (t))
2197 {
2198 return (uentry_isMutableDatatype
2199 (usymtab_getTypeEntry (ctype_typeId (t))));
2200 }
2201 else
2202 {
2203 return (ctype_isPointer (ctype_realType (t)));
28bf4b0b 2204 /*!! || ctype_isStructorUnion (ctype_realType (t))); */
616915dd 2205 }
2206}
2207
2208bool ctype_isRefCounted (ctype t)
2209{
2210 if (ctype_isUA (t))
2211 {
2212 return (uentry_isRefCountedDatatype
2213 (usymtab_getTypeEntry (ctype_typeId (t))));
2214 }
2215
2216 return FALSE;
2217}
2218
2219bool ctype_isVisiblySharable (ctype t)
2220{
2221 if (ctype_isUnknown (t)) return TRUE;
2222
2223 if (ctype_isConj (t))
2224 {
2225 return (ctype_isVisiblySharable (ctype_getConjA (t))
2226 || ctype_isVisiblySharable (ctype_getConjB (t)));
2227 }
2228
2229 if (ctype_isMutable (t))
2230 {
2231 if (ctype_isUA (t))
2232 {
2233 ctype rt = ctype_realType (t);
2234
2235 if (rt == t)
2236 {
2237 return TRUE;
2238 }
2239 else
2240 {
2241 return ctype_isVisiblySharable (rt);
28bf4b0b 2242
616915dd 2243 }
2244 }
2245 else
2246 {
2247 return TRUE;
2248 }
2249 }
2250
2251 return FALSE;
2252}
2253
2254# if 0
2255/* Replaced by ctype_isMutable (more sensible) */
2256bool ctype_canAlias (ctype ct)
2257{
2258 /* can ct refer to memory locations?
2259 ** ==> a pointer or a mutable abstract type
2260 ** arrays?
2261 */
2262
2263 ctype tr = ctype_realType (ct);
2264
2265 return (ctype_isPointer (tr) || ctype_isMutable (ct) || ctype_isStructorUnion (tr));
2266}
2267# endif
2268
2269/*
2270** c1 is the dominant type; c2 is the modifier type
2271**
2272** eg. double + long int => long double
2273*/
2274
2275ctype ctype_combine (ctype dominant, ctype modifier)
2276{
2277 DPRINTF (("Combine: %s + %s",
2278 ctype_unparse (dominant),
2279 ctype_unparse (modifier)));
2280
2281 if (ctype_isConj (dominant))
2282 {
2283 ctype res;
2284
2285 if (ctype_isExplicitConj (dominant))
2286 {
2287 res = ctype_makeExplicitConj (ctype_combine (ctype_getConjA (dominant),
2288 modifier),
2289 ctype_getConjB (dominant));
2290 }
2291 else
2292 {
2293 res = ctype_makeConj (ctype_combine (ctype_getConjA (dominant),
2294 modifier),
2295 ctype_getConjB (dominant));
2296 }
2297
2298 return res;
2299 }
2300
2301 if (ctype_isUnknown (modifier))
2302 {
2303 return dominant;
2304 }
2305 else if (ctype_isUnknown (dominant))
2306 {
2307 return modifier;
2308 }
2309 else
2310 {
2311 if (ctype_isEnum (dominant)) dominant = ctype_int;
2312 if (ctype_isEnum (modifier)) modifier = ctype_int;
2313
2314 if (modifier == ctype_uint)
2315 {
2316 if (dominant == ctype_int) return ctype_uint;
2317 if (dominant == ctype_lint) return ctype_ulint;
2318 if (dominant == ctype_sint) return ctype_usint;
2319 if (dominant == ctype_char) return ctype_uchar;
2320
2321 /* evs 2000-07-28: added this line */
2322 if (dominant == ctype_llint) return ctype_ullint;
2323
2324 if ((dominant == ctype_uint) || dominant == ctype_uchar)
2325 {
2326 voptgenerror (FLG_DUPLICATEQUALS,
2327 message ("Duplicate unsigned qualifier"),
2328 g_currentloc);
2329
2330 return ctype_uint;
2331 }
2332 else
2333 {
2334 voptgenerror (FLG_DUPLICATEQUALS,
2335 message ("Type qualifier unsigned used with %s",
2336 ctype_unparse (dominant)),
2337 g_currentloc);
2338
2339 return dominant;
2340 }
2341 }
2342 else if (modifier == ctype_llint)
2343 {
2344 if (dominant == ctype_int)
2345 {
2346 return ctype_llint;
2347 }
2348
2349 voptgenerror (FLG_DUPLICATEQUALS,
2350 message ("Duplicate long qualifier on non-int"),
2351 g_currentloc);
2352 }
2353 else if (modifier == ctype_lint)
2354 {
2355 if (dominant == ctype_int) return ctype_lint;
2356 if (dominant == ctype_uint) return ctype_ulint;
2357 if (dominant == ctype_double) return ctype_ldouble;
2358
2359 if (dominant == ctype_lint || dominant == ctype_ulint
2360 || dominant == ctype_sint || dominant == ctype_usint
2361 || dominant == ctype_ldouble)
2362 {
2363 if (dominant == ctype_lint)
2364 {
2365 /* long long not supported by ANSI */
2366 return ctype_llint;
2367 }
2368
28bf4b0b 2369 /* ++jimz */
2370 if (dominant == ctype_ulint)
2371 {
2372 /* unsigned long long not supported by ANSI */
2373 return ctype_ullint;
2374 }
2375 /* ==jimz */
2376
616915dd 2377 if (dominant == ctype_sint || dominant == ctype_usint)
2378 {
2379 if (!context_getFlag (FLG_IGNOREQUALS))
2380 {
2381 llerrorlit (FLG_SYNTAX,
2382 "Contradictory long and short type qualifiers");
2383 }
2384 }
2385 else
2386 {
2387 voptgenerror (FLG_DUPLICATEQUALS,
2388 message ("Duplicate long qualifier"),
2389 g_currentloc);
2390 }
2391
2392 return ctype_lint;
2393 }
2394 }
2395 else if (modifier == ctype_sint)
2396 {
2397 if (dominant == ctype_int) return ctype_sint;
2398 if (dominant == ctype_uint) return ctype_usint;
2399
2400 if (dominant == ctype_sint || dominant == ctype_usint)
2401 {
2402 voptgenerror (FLG_DUPLICATEQUALS,
2403 message ("Duplicate short qualifier"),
2404 g_currentloc);
2405 return ctype_uint;
2406 }
2407 else if (dominant == ctype_lint)
2408 {
2409 if (!context_getFlag (FLG_IGNOREQUALS))
2410 {
2411 llerrorlit (FLG_SYNTAX,
2412 "Contradictory long and short type qualifiers");
2413 }
2414
2415 return dominant;
2416 }
28bf4b0b 2417/* ++jimz */
2418 else if (dominant == ctype_llint)
2419 {
2420 if (!context_getFlag (FLG_IGNOREQUALS))
2421 {
2422 llerrorlit (FLG_SYNTAX,
2423 "Contradictory long long and short type qualifiers");
2424 }
2425
2426 return dominant;
2427 }
2428/* ==jimz */
616915dd 2429 else
2430 {
2431 if (!context_getFlag (FLG_IGNOREQUALS))
2432 {
2433 llerror (FLG_SYNTAX,
2434 message ("Type qualifier short used with %s",
2435 ctype_unparse (dominant)));
2436 }
2437
2438 return dominant;
2439 }
2440 }
2441 else if (modifier == ctype_ulint)
2442 {
2443 if (dominant == ctype_int) return modifier;
2444
2445 if (dominant == ctype_lint || dominant == ctype_ulint)
2446 {
2447 voptgenerror (FLG_DUPLICATEQUALS,
2448 message ("Duplicate long qualifier"),
2449 g_currentloc);
2450
2451 return modifier;
2452 }
2453
2454 if (dominant == ctype_uint || dominant == ctype_usint)
2455 {
2456 voptgenerror (FLG_DUPLICATEQUALS,
2457 message ("Duplicate unsigned qualifier"),
2458 g_currentloc);
2459
2460 return modifier;
2461 }
2462
2463 if (dominant == ctype_sint || dominant == ctype_usint)
2464 {
2465 if (!context_getFlag (FLG_IGNOREQUALS))
2466 {
2467 llerrorlit (FLG_SYNTAX,
2468 "Contradictory long and short type qualifiers");
2469 }
2470
2471 return dominant;
2472 }
2473
2474 if (!context_getFlag (FLG_IGNOREQUALS))
2475 {
2476 llerror (FLG_SYNTAX,
2477 message ("Type qualifiers unsigned long used with %s",
2478 ctype_unparse (dominant)));
2479 }
2480
2481 return dominant;
2482 }
2483 else if (modifier == ctype_usint)
2484 {
2485 if (dominant == ctype_int) return modifier;
2486
2487 if (dominant == ctype_sint || dominant == ctype_usint)
2488 {
2489 voptgenerror (FLG_DUPLICATEQUALS,
2490 message ("Duplicate short qualifier"),
2491 g_currentloc);
2492 return modifier;
2493 }
2494
2495 if (dominant == ctype_uint)
2496 {
2497 voptgenerror (FLG_DUPLICATEQUALS,
2498 message ("Duplicate unsigned qualifier"),
2499 g_currentloc);
2500
2501 return modifier;
2502 }
2503
2504 if (dominant == ctype_lint || dominant == ctype_ulint
2505 || dominant == ctype_llint)
2506 {
2507 if (!context_getFlag (FLG_IGNOREQUALS))
2508 {
2509 llerrorlit (FLG_SYNTAX,
2510 "Contradictory long and short type qualifiers");
2511 }
2512
2513 return dominant;
2514 }
2515
2516 if (!context_getFlag (FLG_IGNOREQUALS))
2517 {
2518 llerror (FLG_SYNTAX,
2519 message ("Type qualifiers unsigned short used with %s",
2520 ctype_unparse (dominant)));
2521 }
2522
2523 return dominant;
2524 }
2525 else
2526 {
2527 ;
2528 }
2529
2530 return dominant;
2531 }
2532}
2533
2534ctype ctype_resolve (ctype c)
2535{
2536 if (ctype_isUnknown (c)) return ctype_int;
2537 return c;
2538}
2539
2540ctype ctype_fromQual (qual q)
2541{
2542 if (qual_isSigned (q)) return ctype_int;
2543 if (qual_isUnsigned (q)) return ctype_uint;
2544 if (qual_isLong (q)) return ctype_lint;
2545 if (qual_isShort (q)) return ctype_sint;
2546
2547 llcontbug (message ("ctype_fromQual: invalid qualifier: %s", qual_unparse (q)));
2548 return ctype_unknown;
2549}
2550
2551bool
2552ctype_isAnyFloat (ctype c)
2553{
2554 return (cprim_isAnyReal (ctype_toCprim (c)));
2555}
2556
2557bool
2558ctype_isUnsigned (ctype c)
2559{
2560 if (ctype_isConj (c))
2561 return (ctype_isUnsigned (ctype_getConjA (c)) ||
2562 ctype_isUnsigned (ctype_getConjB (c)));
2563
2564 return (c == ctype_uint || c == ctype_uchar
2565 || c == ctype_usint || c == ctype_ulint
28bf4b0b 2566 || c == ctype_ullint
616915dd 2567 || c == ctype_unsignedintegral);
2568}
2569
28bf4b0b 2570/* ++jimz */
2571static bool
2572ctype_isLongLong (ctype c)
2573{
2574 if (ctype_isConj (c))
2575 return (ctype_isLongLong (ctype_getConjA (c)) ||
2576 ctype_isLongLong (ctype_getConjB (c)));
2577
2578 return (c == ctype_llint || c == ctype_ullint);
2579}
2580/* ==jimz */
2581
616915dd 2582static bool
2583ctype_isLong (ctype c)
2584{
2585 if (ctype_isConj (c))
2586 return (ctype_isLong (ctype_getConjA (c)) ||
2587 ctype_isLong (ctype_getConjB (c)));
2588
2589 return (c == ctype_lint || c == ctype_ulint);
2590}
2591
2592static bool
2593ctype_isShort (ctype c)
2594{
2595 if (ctype_isConj (c))
2596 return (ctype_isShort (ctype_getConjA (c)) ||
2597 ctype_isShort (ctype_getConjB (c)));
2598
2599 return (c == ctype_sint || c == ctype_usint);
2600}
2601
2602bool
2603ctype_isStackAllocated (ctype c)
2604{
2605 ctype ct = ctype_realType (c);
2606
2607 if (ctype_isConj (ct))
2608 return (ctype_isStackAllocated (ctype_getConjA (ct)) ||
2609 ctype_isStackAllocated (ctype_getConjB (ct)));
2610
2611 return (ctype_isArray (c) || ctype_isSU (c));
2612}
2613
2614static bool ctype_isMoreUnsigned (ctype c1, ctype c2)
2615{
2616 return (ctype_isUnsigned (c1) && !ctype_isUnsigned (c2));
2617}
2618
2619static bool ctype_isLonger (ctype c1, ctype c2)
2620{
28bf4b0b 2621 /* 2001-06-10: Fix for long long's provided by Jim Zelenka */
616915dd 2622 return ((ctype_isDouble (c1) && !ctype_isDouble (c2))
28bf4b0b 2623 || (ctype_isLongLong (c1) && !ctype_isLongLong (c2))
2624 || (ctype_isLong (c1)
2625 && (!ctype_isLong (c2)) && (!ctype_isLongLong (c2)))
616915dd 2626 || (ctype_isShort (c2) && !ctype_isShort (c1)));
2627}
2628
2629ctype
2630ctype_widest (ctype c1, ctype c2)
2631{
28bf4b0b 2632 if (ctype_isMoreUnsigned (c2, c1) || ctype_isLonger (c2, c1))
616915dd 2633 {
2634 return c2;
2635 }
2636 else
2637 {
2638 return c1;
2639 }
2640}
2641
28bf4b0b 2642static /*@observer@*/ ctbase ctype_getCtbase (ctype c)
2643{
2644 /*@+enumint@*/
2645 if (c >= 0 && c < cttab.size)
2646 {
2647 return (cttab.entries[c]->ctbase);
2648 }
2649 else
2650 {
2651 if (c == ctype_unknown)
2652 llbuglit ("ctype_getCtbase: ctype unknown");
2653 if (c == ctype_undefined)
2654 llbuglit ("ctype_getCtbase: ctype undefined");
2655 if (c == ctype_dne)
2656 llbuglit ("ctype_getCtbase: ctype dne");
2657 if (c == ctype_elipsMarker)
2658 llbuglit ("ctype_getCtbase: elips marker");
2659
2660 llfatalbug (message ("ctype_getCtbase: ctype out of range: %d", c));
2661 BADEXIT;
2662 }
2663
2664 /*@=enumint@*/
2665}
2666
2667static /*@notnull@*/ /*@observer@*/ ctbase
2668ctype_getCtbaseSafe (ctype c)
2669{
2670 ctbase res = ctype_getCtbase (c);
2671
2672 llassert (ctbase_isDefined (res));
2673 return res;
2674}
2675
2676/*
2677** ctentry
2678*/
2679
2680static ctentry
2681ctype_getCtentry (ctype c)
2682{
2683 static /*@only@*/ ctentry errorEntry = NULL;
2684
2685 if (cttab.size == 0)
2686 {
2687 if (errorEntry == NULL)
2688 {
2689 errorEntry = ctentry_makeNew (CTK_UNKNOWN, ctbase_undefined);
2690 }
2691
2692 return errorEntry;
2693 }
2694
2695 /*@+enumint@*/
2696 if (c >= CTK_PLAIN && c < cttab.size)
2697 {
2698 return (cttab.entries[c]);
2699 }
2700 else if (c == CTK_UNKNOWN)
2701 llcontbuglit ("ctype_getCtentry: ctype unknown");
2702 else if (c == CTK_INVALID)
2703 llcontbuglit ("ctype_getCtentry: ctype invalid (ctype_undefined)");
2704 else if (c == CTK_DNE)
2705 llcontbuglit ("ctype_getCtentry: ctype dne");
2706 else if (c == CTK_ELIPS)
2707 llcontbuglit ("ctype_getCtentry: ctype elipsis");
2708 else if (c == CTK_MISSINGPARAMS)
2709 llcontbuglit ("ctype_getCtentry: ctype missing params");
2710 else
2711 llbug (message ("ctype_getCtentry: ctype out of range: %d", c));
2712
2713 return (cttab.entries[ctype_unknown]);
2714 /*@=enumint@*/
2715}
2716
0e5499ac 2717
2718bool ctype_isFixedArray (ctype c)
2719{
2720 if (ctype_isElips (c)) return FALSE;
2721
2722 return (ctbase_isFixedArray (ctype_getCtbaseSafe (c)));
2723}
2724
2725
616915dd 2726/*drl 11/28/2000 */
2727/* requires that the type is an fixed array */
2728/* return the size of the array */
2729
2730long int ctype_getArraySize (ctype c)
2731{
28bf4b0b 2732 long int size;
0e5499ac 2733
616915dd 2734 ctbase ctb;
616915dd 2735
7534721d 2736 llassert (ctype_isFixedArray (c));
616915dd 2737
0e5499ac 2738 ctb = ctype_getCtbaseSafe(c);
28bf4b0b 2739 size = ctbase_getArraySize (ctb);
616915dd 2740
7534721d 2741 DPRINTF ((message ("ctype_getArraySize: got fixed array size of %s / %d ",
2742 ctype_unparse (c),
2743 (int) size)));
28bf4b0b 2744 return size;
616915dd 2745}
28bf4b0b 2746
This page took 1.7805 seconds and 5 git commands to generate.