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
which(s)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
findsym(s,f)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
findclass(s,cl)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