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