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