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[] = "@(#)which.c 8.1 (Berkeley) 06/06/93"; 10 #endif /* not lint */ 11 12 /* 13 * Routines to distinguish symbols of the same name. 14 */ 15 16 #include "defs.h" 17 #include "sym.h" 18 #include "classes.h" 19 #include "symtab.h" 20 #include "mappings.h" 21 #include "machine.h" 22 #include "sym.rep" 23 24 /* 25 * Figure out the "current" symbol being referred to, 26 * this is either the active one or the most visible from the 27 * current scope. 28 * 29 * Fields are purposely ignored; these can be gotten to via "findclass". 30 */ 31 32 SYM *which(s) 33 SYM *s; 34 { 35 register SYM *p, *t, *f; 36 37 if (s == program || isbuiltin(s)) { 38 return(s); 39 } 40 if (!isactive(program)) { 41 f = program; 42 } else { 43 f = whatblock(pc); 44 if (f == NIL) { 45 panic("no block for addr 0x%x", pc); 46 } 47 } 48 for (p = f; p != NIL; p = p->func) { 49 if ((t = findsym(s, p)) != NIL) { 50 break; 51 } 52 } 53 if (t == NIL) { 54 error("\"%s\" is not known in \"%s\"", s->symbol, f->symbol); 55 } 56 return(t); 57 } 58 59 /* 60 * Find a (non-field) symbol with name s->symbol belonging to block f. 61 * 62 * Parameters to the main program are purposely "not found" because 63 * pi gives them no type. 64 */ 65 66 SYM *findsym(s, f) 67 SYM *s; 68 SYM *f; 69 { 70 register SYM *t; 71 72 if (!isblock(f)) { 73 error("%s is not a block", f->symbol); 74 } 75 for (t = s; t != NIL; t = t->next_sym) { 76 if (t->func == f && !(f == program && isparam(t)) && 77 t->class != FIELD && streq(t->symbol, s->symbol)) { 78 break; 79 } 80 } 81 return(t); 82 } 83 84 /* 85 * Find the symbol which is has the same name and scope as the 86 * given symbol but is of the given field. Return NIL if there is none. 87 */ 88 89 SYM *findclass(s, cl) 90 SYM *s; 91 char cl; 92 { 93 register SYM *t; 94 95 if (s->class == cl) { 96 return(s); 97 } 98 t = st_lookup(symtab, s->symbol); 99 while (t != NIL && (t->class != cl || t->func != s->func || 100 !streq(s->symbol, t->symbol))) { 101 t = t->next_sym; 102 } 103 return(t); 104 } 105