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