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 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 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 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 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 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 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 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 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