123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358 |
- /* $Id$ */
- /* Symbol handling */
- #include <stdio.h>
- #include <alloc.h>
- #include <out.h>
- #include <stb.h>
- #include <assert.h>
- #include "position.h"
- #include "file.h"
- #include "idf.h"
- #include "type.h"
- #include "symbol.h"
- #include "scope.h"
- #include "tree.h"
- #include "operator.h"
- #include "misc.h"
- p_symbol currfile, listfile;
- extern FILE *db_out;
- p_symbol
- NewSymbol(s, scope, class, nam)
- char *s;
- register p_scope scope;
- struct outname *nam;
- {
- register p_symbol sym;
-
- sym = new_symbol();
- sym->sy_idf = str2idf(s, 0);
- sym->sy_scope = scope;
- sym->sy_prev_sc = scope->sc_symbs;
- scope->sc_symbs = sym;
- sym->sy_next = sym->sy_idf->id_def;
- sym->sy_idf->id_def = sym;
- sym->sy_class = class;
- switch(class) {
- case MODULE:
- case PROC:
- case FUNCTION:
- case VAR:
- case REGVAR:
- case LOCVAR:
- case VARPAR:
- sym->sy_name.nm_value = nam->on_valu;
- break;
- default:
- break;
- }
- return sym;
- }
- /* Lookup a definition for 'id' in scope 'scope' with class in the 'class'
- bitset.
- */
- p_symbol
- Lookup(id, scope, class)
- struct idf *id;
- p_scope scope;
- int class;
- {
- register p_symbol p = id ? id->id_def : 0;
- while (p) {
- if (p->sy_scope == scope && (p->sy_class & class)) {
- return p;
- }
- p = p->sy_next;
- }
- return (p_symbol) 0;
- }
- /* Lookup a definition for 'id' with class in the 'class' bitset,
- starting in scope 'sc' and also looking in enclosing scopes.
- */
- p_symbol
- Lookfromscope(id, class, sc)
- register struct idf *id;
- int class;
- register p_scope sc;
- {
- if (! id) return (p_symbol) 0;
- while (sc) {
- register p_symbol sym = id->id_def;
- while (sym) {
- if (sym->sy_scope == sc && (sym->sy_class & class)) {
- return sym;
- }
- sym = sym->sy_next;
- }
- sc = sc->sc_static_encl;
- }
- return (p_symbol) 0;
- }
- extern char *strrindex();
- p_symbol
- add_file(s)
- char *s;
- {
- register p_symbol sym = NewSymbol(s,
- PervasiveScope,
- FILESYM,
- (struct outname *) 0);
- register char *p;
- sym->sy_file = new_file();
- sym->sy_file->f_sym = sym;
- p = strrindex(s, '.');
- if (p) {
- char c = *p;
- p_symbol sym1;
- *p = 0;
- s = Salloc(s, (unsigned) strlen(s)+1);
- *p = c;
- sym1 = NewSymbol(s,
- PervasiveScope,
- FILELINK,
- (struct outname *) 0);
- sym1->sy_filelink = sym;
- sym->sy_file->f_base = sym1;
- }
- return sym;
- }
- static p_scope
- def_scope(s)
- p_symbol s;
- {
- switch(s->sy_class) {
- case FILELINK:
- s = s->sy_filelink;
- /* fall through */
- case FILESYM:
- return s->sy_file->f_scope;
- case PROC:
- case FUNCTION:
- case MODULE:
- case TYPE:
- case VAR:
- case REGVAR:
- case LOCVAR:
- case VARPAR:
- return s->sy_name.nm_scope;
- }
- return 0;
- }
- /* Determine if the OP_SELECT tree indicated by 'p' could lead to scope 'sc'.
- */
- int
- consistent(p, sc)
- p_tree p;
- p_scope sc;
- {
- p_tree arg;
- p_symbol sym;
- p_scope target_sc;
- assert(p->t_oper == OP_SELECT);
- p = p->t_args[0];
- switch(p->t_oper) {
- case OP_NAME:
- #define CLASS (FILELINK|FILESYM|PROC|FUNCTION|MODULE|TYPE|VAR|REGVAR|LOCVAR|VARPAR|LBOUND|UBOUND)
- sym = Lookfromscope(p->t_idf, CLASS, sc->sc_static_encl);
- if (sym) {
- int precise = 1;
- target_sc = def_scope(sym);
- while (sc && sc != target_sc) {
- precise = 0;
- sc = sc->sc_static_encl;
- }
- return sc == 0 ? 0 : precise + 1 ;
- }
- return 0;
- case OP_SELECT:
- arg = p->t_args[1];
- sym = Lookfromscope(arg->t_idf, CLASS, sc->sc_static_encl);
- if (sym) {
- int precise = 1;
- target_sc = def_scope(sym);
- while (sc && sc != target_sc) {
- precise = 0;
- sc = sc->sc_static_encl;
- }
- if (sc == 0) return 0;
- if (precise) return consistent(p, sym->sy_scope);
- return consistent(p, sym->sy_scope) != 0;
- }
- return 0;
- default:
- assert(0);
- }
- return 0; /* notreached? */
- }
- /* Try to find the name referred to in the node indicated by 'p', and
- try to be just a little bit intelligent about it.
- */
- p_symbol
- identify(p, class_set)
- p_tree p;
- int class_set;
- {
- p_symbol sym = 0, sym1 = 0;
- register p_symbol s;
- p_tree arg;
- int precise = 0;
- switch(p->t_oper) {
- case OP_NAME:
- sym = Lookfromscope(p->t_idf, class_set, CurrentScope);
- if (sym) {
- /* Found it. */
- break;
- }
- /* We could not find it using the current scope; now we try to identify
- it using class_set. If this results in only one definition, we
- take this one.
- */
- s = p->t_idf->id_def;
- while (s) {
- if (s->sy_class & class_set) {
- if (sym) {
- error("could not identify \"%s\"", p->t_str);
- sym = 0;
- break;
- }
- sym = s;
- }
- s = s->sy_next;
- }
- if (!sym && !s) {
- error("could not find \"%s\"", p->t_str);
- }
- break;
- case OP_SELECT:
- arg = p->t_args[1];
- assert(arg->t_oper == OP_NAME);
- s = arg->t_idf->id_def;
- while (s) {
- int temp;
- if ((s->sy_class & class_set) &&
- (temp = consistent(p, s->sy_scope))) {
- if (temp > precise) {
- sym = s;
- precise = temp;
- sym1 = 0;
- }
- else if (sym && temp == precise) sym1 = s;
- }
- s = s->sy_next;
- }
- if (sym && sym1) {
- error("could not identify \"%s\"", arg->t_str);
- return 0;
- }
- if (!sym && !s) {
- error("could not find \"%s\"", arg->t_str);
- return 0;
- }
- break;
- default:
- assert(0);
- }
- return sym;
- }
- static
- pr_scopes(sc)
- p_scope sc;
- {
- if (! sc) return;
- pr_scopes(sc->sc_static_encl);
- if (sc->sc_definedby) {
- if (sc->sc_definedby->sy_class == FILESYM &&
- sc->sc_definedby->sy_file->f_base) {
- fprintf(db_out, "%s`", sc->sc_definedby->sy_file->f_base->sy_idf->id_text);
- }
- else fprintf(db_out, "%s`", sc->sc_definedby->sy_idf->id_text);
- }
- }
- pr_sym(s)
- p_symbol s;
- {
- switch(s->sy_class) {
- case CONST:
- fprintf(db_out, "Constant:\t");
- break;
- case TYPE:
- fprintf(db_out, "Type:\t\t");
- break;
- case TAG:
- fprintf(db_out, "Tag:\t\t");
- break;
- case MODULE:
- fprintf(db_out, "Module:\t\t");
- break;
- case PROC:
- case FUNCTION:
- fprintf(db_out, "Routine:\t");
- break;
- case VAR:
- case REGVAR:
- case LOCVAR:
- case VARPAR:
- case LBOUND:
- case UBOUND:
- fprintf(db_out, "Variable:\t");
- break;
- case FIELD:
- fprintf(db_out, "Field:\t\t");
- break;
- case FILESYM:
- case FILELINK:
- fprintf(db_out, "File:\t\t");
- break;
- default:
- assert(0);
- }
- pr_scopes(s->sy_scope);
- fprintf(db_out, "%s\n", s->sy_idf->id_text);
- }
- resolve_cross(tp)
- p_type tp;
- {
- register p_symbol sym = tp->ty_sym->sy_idf->id_def;
- while (sym) {
- if (sym->sy_class == TAG &&
- sym->sy_type->ty_class == T_CROSS &&
- sym->sy_type->ty_cross == (p_type) 0 &&
- sym->sy_type->ty_size == tp->ty_class &&
- scope_encloses(tp->ty_sym->sy_scope, sym->sy_scope)) {
- sym->sy_type->ty_cross = tp;
- sym->sy_type->ty_size = tp->ty_size;
- }
- sym = sym->sy_next;
- }
- }
|