148093Sbostic /*-
2*62149Sbostic * Copyright (c) 1980, 1993
3*62149Sbostic * The Regents of the University of California. All rights reserved.
448093Sbostic *
548093Sbostic * %sccs.include.redist.c%
622529Sdist */
75532Slinton
822529Sdist #ifndef lint
9*62149Sbostic static char sccsid[] = "@(#)which.c 8.1 (Berkeley) 06/06/93";
1048093Sbostic #endif /* not lint */
115532Slinton
125532Slinton /*
135532Slinton * Routines to distinguish symbols of the same name.
145532Slinton */
155532Slinton
165532Slinton #include "defs.h"
175532Slinton #include "sym.h"
185532Slinton #include "classes.h"
195532Slinton #include "symtab.h"
205532Slinton #include "mappings.h"
215532Slinton #include "machine.h"
225532Slinton #include "sym.rep"
235532Slinton
245532Slinton /*
255532Slinton * Figure out the "current" symbol being referred to,
265532Slinton * this is either the active one or the most visible from the
275532Slinton * current scope.
285532Slinton *
295532Slinton * Fields are purposely ignored; these can be gotten to via "findclass".
305532Slinton */
315532Slinton
which(s)325532Slinton SYM *which(s)
335532Slinton SYM *s;
345532Slinton {
355532Slinton register SYM *p, *t, *f;
365532Slinton
375532Slinton if (s == program || isbuiltin(s)) {
385532Slinton return(s);
395532Slinton }
405532Slinton if (!isactive(program)) {
415532Slinton f = program;
425532Slinton } else {
435532Slinton f = whatblock(pc);
445532Slinton if (f == NIL) {
455532Slinton panic("no block for addr 0x%x", pc);
465532Slinton }
475532Slinton }
485532Slinton for (p = f; p != NIL; p = p->func) {
495532Slinton if ((t = findsym(s, p)) != NIL) {
505532Slinton break;
515532Slinton }
525532Slinton }
535532Slinton if (t == NIL) {
545532Slinton error("\"%s\" is not known in \"%s\"", s->symbol, f->symbol);
555532Slinton }
565532Slinton return(t);
575532Slinton }
585532Slinton
595532Slinton /*
605532Slinton * Find a (non-field) symbol with name s->symbol belonging to block f.
615532Slinton *
625532Slinton * Parameters to the main program are purposely "not found" because
635532Slinton * pi gives them no type.
645532Slinton */
655532Slinton
findsym(s,f)665532Slinton SYM *findsym(s, f)
675532Slinton SYM *s;
685532Slinton SYM *f;
695532Slinton {
705532Slinton register SYM *t;
715532Slinton
725532Slinton if (!isblock(f)) {
735532Slinton error("%s is not a block", f->symbol);
745532Slinton }
755532Slinton for (t = s; t != NIL; t = t->next_sym) {
765532Slinton if (t->func == f && !(f == program && isparam(t)) &&
775532Slinton t->class != FIELD && streq(t->symbol, s->symbol)) {
785532Slinton break;
795532Slinton }
805532Slinton }
815532Slinton return(t);
825532Slinton }
835532Slinton
845532Slinton /*
855532Slinton * Find the symbol which is has the same name and scope as the
865532Slinton * given symbol but is of the given field. Return NIL if there is none.
875532Slinton */
885532Slinton
findclass(s,cl)895532Slinton SYM *findclass(s, cl)
905532Slinton SYM *s;
915532Slinton char cl;
925532Slinton {
935532Slinton register SYM *t;
945532Slinton
955532Slinton if (s->class == cl) {
965532Slinton return(s);
975532Slinton }
985532Slinton t = st_lookup(symtab, s->symbol);
995532Slinton while (t != NIL && (t->class != cl || t->func != s->func ||
1005532Slinton !streq(s->symbol, t->symbol))) {
1015532Slinton t = t->next_sym;
1025532Slinton }
1035532Slinton return(t);
1045532Slinton }
105