1 /*-
2 * Copyright (c) 1980, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * %sccs.include.redist.c%
6 */
7
8 #ifndef lint
9 static char sccsid[] = "@(#)predicates.c 8.1 (Berkeley) 06/06/93";
10 #endif /* not lint */
11
12 /*
13 * The basic tests on a symbol.
14 */
15
16 #include "defs.h"
17 #include "sym.h"
18 #include "symtab.h"
19 #include "btypes.h"
20 #include "classes.h"
21 #include "sym.rep"
22
23 /*
24 * Test if a symbol is a parameter. This is true if there
25 * is a cycle from s->func to s via chain pointers.
26 */
27
isparam(s)28 BOOLEAN isparam(s)
29 SYM *s;
30 {
31 register SYM *t;
32
33 for (t = s->func; t != NIL; t = t->chain) {
34 if (t == s) {
35 return(TRUE);
36 }
37 }
38 return(FALSE);
39 }
40
41 /*
42 * Test if a symbol is a var parameter, i.e. has class REF.
43 */
44
isvarparam(s)45 BOOLEAN isvarparam(s)
46 SYM *s;
47 {
48 return (BOOLEAN) s->class == REF;
49 }
50
51 /*
52 * Test if a symbol is a variable (actually any addressible quantity
53 * with do).
54 */
55
isvariable(s)56 BOOLEAN isvariable(s)
57 SYM *s;
58 {
59 return s->class == VAR || s->class == FVAR || s->class == REF;
60 }
61
62 /*
63 * Test if a symbol is a block, e.g. function, procedure, or the
64 * main program.
65 */
66
isblock(s)67 BOOLEAN isblock(s)
68 register SYM *s;
69 {
70 return(s->class == FUNC || s->class == PROC || s->class == PROG);
71 }
72
73 /*
74 * Test if a symbol is builtin, that is, a predefined type or
75 * reserved word.
76 */
77
isbuiltin(s)78 BOOLEAN isbuiltin(s)
79 SYM *s;
80 {
81 return(s->blkno == 0 && s->class != PROG && s->class != VAR);
82 }
83
84 /*
85 * Compatible tests if two types are compatible. The issue
86 * is complicated a bit by ranges.
87 *
88 * Integers and reals are not compatible since they cannot always be mixed.
89 */
90
compatible(t1,t2)91 BOOLEAN compatible(t1, t2)
92 register SYM *t1, *t2;
93 {
94 register BOOLEAN b;
95
96 if (isvariable(t1)) {
97 t1 = t1->type;
98 }
99 if (isvariable(t2)) {
100 t2 = t2->type;
101 }
102 if (t1 == t2) {
103 b = TRUE;
104 } else {
105 t1 = rtype(t1);
106 t2 = rtype(t2);
107 if (t1->type == t2->type) {
108 if (t1->class == RANGE && t2->class == RANGE) {
109 b = TRUE;
110 } else if ((t1->class == SCAL || t1->class == CONST) &&
111 (t2->class == SCAL || t2->class == CONST)) {
112 b = TRUE;
113 } else if (t1->type == t_char &&
114 t1->class == ARRAY && t2->class == ARRAY) {
115 b = TRUE;
116 } else {
117 b = FALSE;
118 }
119 /*
120 * A kludge here for "nil". Should be handled better.
121 * Opens a pandora's box for integer/pointer compatibility.
122 */
123 } else if ((t1->class == RANGE && t2->class == PTR) ||
124 (t2->class == RANGE && t1->class == PTR)) {
125 b = TRUE;
126 } else {
127 b = FALSE;
128 }
129 }
130 return b;
131 }
132
133 /*
134 * Predicate to test if a symbol should be printed. We don't print
135 * files, for example, simply because there's no good way to do it.
136 * The symbol must be within the given function.
137 */
138
should_print(s,f)139 BOOLEAN should_print(s, f)
140 SYM *s;
141 SYM *f;
142 {
143 SYM *t;
144
145 if (s->func != f || (s->class != VAR && s->class != FVAR)) {
146 return(FALSE);
147 } else if (s->chain != NIL) {
148 return(FALSE);
149 } else {
150 t = rtype(s->type);
151 if (t == NIL || t->class == FILET || t->class == SET) {
152 return(FALSE);
153 } else {
154 return(TRUE);
155 }
156 }
157 }
158
159 /*
160 * Test if the name of a symbol is uniquely defined or not.
161 */
162
isambiguous(s)163 BOOLEAN isambiguous(s)
164 SYM *s;
165 {
166 SYM *t;
167
168 t = st_lookup(symtab, s->symbol);
169 if (t == NIL) {
170 panic("symbol name vanished");
171 }
172 while (t != NIL && (s == t || !streq(t->symbol, s->symbol))) {
173 t = t->next_sym;
174 }
175 return t != NIL;
176 }
177