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