📄 symbols.c
字号:
/*@(#)symbols.c 4.2 Ultrix 11/9/90*//************************************************************************ * * * Copyright (c) 1986 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * This software is derived from software received from the * * University of California, Berkeley, and from Bell * * Laboratories. Use, duplication, or disclosure is subject to * * restrictions under license agreements with University of * * California and with AT&T. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************//************************************************************************ * * * Modification History * * * * 011 - Modified which() for VAX FORTRAN. f77 forces identifiers * * to lower-case, while fort forces them to upper-case. A * * failed nametable search now results in further attempt(s),* * using all lower- and/or upper-case. * * (Bob Neff, March 28, 1990) * * * * 010 - Fixed erroneous type mismatch. * * (Lee Miller, Jan 24, 1990) * * * * 009 - Added support for vectors. * * (L Miller, 18JAN90) * * * * 008 - Workaround for vcc bug. Panic in several cases of bad * * stab entries that could otherwise lead to infinite loops. * * Also remerged 4.3 changes for correct spacing. * * (Jon Reeves, July 14, 1987) * * * * 007 - Bug fix for spr# ICA-01081. Dbx used to panic when * * doing conditional comparisons of string constants (eg. * * stop at 18 if array[3] == "string" ). * * Conditional string comparisons are not allowed, so dbx * * now emits the appropriate error message (see binaryop()). * * (vjh, May 23, 1986) * * * * 006 - Merged in 4.3 changes. * * (vjh, April 29, 1986) * * * * 005 - Added support for jsb routines. Also, converted * * isinternal() to a macro. Now use one of the "unused" * * bits in the Symbol struct as a boolean jsb flag. * * (vjh, August 9, 1985) * * * * 004 - Added new routine findproc(proc). * * (vjh, July 17, 1985) * * * * 003 - Added a new Symclass: NO_DSTMAP. This is the class * * given to symbols that won't map from a DST to a stab * * (vjh, June 26, 1985) * * * * 002 - Updated all calls to findlanguage() to call with * * LanguageName constant, rather than with a filename * * suffix. * * (vjh, June 22, 1985) * * * * 001 - Added new fields to the Symbol struct for supporting * * register indirection/displacement modes: * * symvalue.raddr.<fields> * * (Victoria Holt, June 22, 1985) * * * ************************************************************************//* * Copyright (c) 1983 Regents of the University of California. * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. */#ifndef lintstatic char *sccsid = "@(#)symbols.c 2.1 ULTRIX 4/24/89";#endif not lint/* * Symbol management. */#include "defs.h"#include "symbols.h"#include "languages.h"#include "printsym.h"#include "tree.h"#include "operators.h"#include "eval.h"#include "mappings.h"#include "events.h"#include "process.h"#include "runtime.h"#include "machine.h"#include "names.h"#include "main.h"#ifndef publictypedef struct Symbol *Symbol;#include "machine.h"#include "names.h"#include "languages.h"#include "tree.h"/* * Symbol classes */typedef enum { BADUSE, CONST, TYPE, VAR, ARRAY, DYNARRAY, SUBARRAY, PTRFILE, RECORD, FIELD, PROC, FUNC, FVAR, REF, PTR, FILET, SET, RANGE, LABEL, WITHPTR, SCAL, STR, PROG, IMPROPER, VARNT, FPROC, FFUNC, MODULE, TAG, COMMON, EXTREF, TYPEREF, NO_DSTMAP} Symclass;typedef enum { R_CONST, R_TEMP, R_ARG, R_ADJUST } Rangetype; struct Symbol { Name name; Language language; Symclass class : 8; Integer level : 8; Symbol type; Symbol chain; union { Node constval; /* value of constant symbol */ int offset; /* variable address */ long iconval; /* integer constant value */ double fconval; /* floating constant value */ int ndims; /* no. of dimensions for dynamic/sub-arrays */ struct { unsigned int reg; Boolean indirect; int displacement; } raddr; struct { /* field offset and size (both in bits) */ int offset; int length; } field; struct { /* common offset and chain; used to relocate */ int offset; /* vars in global BSS */ Symbol chain; } common; struct { /* range bounds */ Rangetype lowertype : 16; Rangetype uppertype : 16; long lower; long upper; } rangev; struct { int offset : 16; /* offset for of function value */ Boolean src : 1; /* true if there is source line info */ Boolean inline : 1; /* true if no separate act. rec. */ Boolean intern : 1; /* internal calling sequence */ Boolean jsb : 1; /* true if is jsb routine */ int unused : 12; Address beginaddr; /* address of function code */ } funcv; struct { /* variant record info */ int size; Symbol vtorec; Symbol vtag; } varnt; String typeref; /* type defined by "<module>:<type>" */ Symbol extref; /* indirect symbol for external reference */ } symvalue; Symbol block; /* symbol containing this symbol */ Symbol next_sym; /* hash chain */};/* * Basic types. */Symbol t_boolean;Symbol t_char;Symbol t_int;Symbol t_real;Symbol t_nil;Symbol t_addr;Symbol t_vquad;Symbol t_vfloat;Symbol t_vhex;Symbol t_vint;Symbol t_vmr;Symbol program;Symbol curfunc;boolean showaggrs;#define symname(s) ident(s->name)#define codeloc(f) ((f)->symvalue.funcv.beginaddr)#define isblock(s) (Boolean) ( \ s->class == FUNC or s->class == PROC or \ s->class == MODULE or s->class == PROG \)#define isroutine(s) (Boolean) ( \ s->class == FUNC or s->class == PROC \)#define isinternal(s) (s->symvalue.funcv.intern)#define jsbroutine(s) (s->symvalue.funcv.jsb)#define nosource(f) (not (f)->symvalue.funcv.src)#define no_dstmap(f) (f->class == NO_DSTMAP)#define isinline(f) ((f)->symvalue.funcv.inline)#define isreg(s) (s->level < 0)#define isvreg(s) (s->level == -4)#include "tree.h"/* * Some macros to make finding a symbol with certain attributes. */#define find(s, withname) \{ \ s = lookup(withname); \ while (s != nil and not (s->name == (withname) and#define where /* qualification */#define endfind(s) )) { \ s = s->next_sym; \ } \}#endif/* * Symbol table structure currently does not support deletions. */#define HASHTABLESIZE 2003private Address regaddr();private Symbol hashtab[HASHTABLESIZE];#define hash(name) ((((unsigned) name) >> 2) mod HASHTABLESIZE)/* * Allocate a new symbol. */#define SYMBLOCKSIZE 100typedef struct Sympool { struct Symbol sym[SYMBLOCKSIZE]; struct Sympool *prevpool;} *Sympool;private Sympool sympool = nil;private Integer nleft = 0;public Symbol symbol_alloc(){ register Sympool newpool; if (nleft <= 0) { newpool = new(Sympool); bzero(newpool, sizeof(*newpool)); newpool->prevpool = sympool; sympool = newpool; nleft = SYMBLOCKSIZE; } --nleft; return &(sympool->sym[nleft]);}public symbol_dump (func)Symbol func;{ register Symbol s; register integer i; printf(" symbols in %s \n",symname(func)); for (i = 0; i < HASHTABLESIZE; i++) { for (s = hashtab[i]; s != nil; s = s->next_sym) { if (s->block == func) { psym(s); } } }}/* * Free all the symbols currently allocated. */public symbol_free(){ Sympool s, t; register Integer i; s = sympool; while (s != nil) { t = s->prevpool; dispose(s); s = t; } for (i = 0; i < HASHTABLESIZE; i++) { hashtab[i] = nil; } sympool = nil; nleft = 0;}/* * Create a new symbol with the given attributes. */public Symbol newSymbol(name, blevel, class, type, chain)Name name;Integer blevel;Symclass class;Symbol type;Symbol chain;{ register Symbol s; s = symbol_alloc(); s->name = name; s->language = primlang; s->level = blevel; s->class = class; s->type = type; s->chain = chain; return s;}/* * Insert a symbol into the hash table. */public Symbol insert(name)Name name;{ register Symbol s; register unsigned int h; h = hash(name); s = symbol_alloc(); s->name = name; s->next_sym = hashtab[h]; hashtab[h] = s; return s;}/* * module lookup. */public Symbol findmodule(name)Name name;{ Symbol s; find(s, name) where ismodule(s) endfind(s); return s;}/* * Symbol lookup. */public Symbol lookup(name)Name name;{ register Symbol s; register unsigned int h; h = hash(name); s = hashtab[h]; while (s != nil and s->name != name) { s = s->next_sym; } return s;}/* Routine to lookup procedure "proc" in the symbol table. */public Symbol findproc(proc)String proc;{ Name n; Symbol s; n = identname(proc, false); find(s, n) where isroutine(s) endfind(s); return s;}/* * Delete a symbol from the symbol table. */public delete (s)Symbol s;{ register Symbol t; register unsigned int h; h = hash(s->name); t = hashtab[h]; if (t == nil) { panic("delete of non-symbol '%s'", symname(s)); } else if (t == s) { hashtab[h] = s->next_sym; } else { while (t->next_sym != s) { t = t->next_sym; if (t == nil) { panic("delete of non-symbol '%s'", symname(s)); } } t->next_sym = s->next_sym; }}/* * Dump out all the variables associated with the given * procedure, function, or program associated with the given stack frame. * * This is quite inefficient. We traverse the entire symbol table * each time we're called. The assumption is that this routine * won't be called frequently enough to merit improved performance. */public dumpvars(f, frame)Symbol f;Frame frame;{ register Integer i; register Symbol s; for (i = 0; i < HASHTABLESIZE; i++) { for (s = hashtab[i]; s != nil; s = s->next_sym) { if (container(s) == f) { if (should_print(s)) { printv(s, frame); putchar('\n'); } else if (s->class == MODULE) { dumpvars(s, frame); } } } }}/* * Create a builtin type. * Builtin types are circular in that btype->type->type = btype. */private Symbol maketype(name, lower, upper)String name;long lower;long upper;{ register Symbol s; Name n; if (name == nil) { n = nil; } else { n = identname(name, true); } s = insert(n); s->language = primlang; s->level = 0; s->class = TYPE; s->type = nil; s->chain = nil; s->type = newSymbol(nil, 0, RANGE, s, nil); s->type->symvalue.rangev.lower = lower; s->type->symvalue.rangev.upper = upper; return s;}/* * Create the builtin symbols. */public symbols_init (){ Symbol s; t_boolean = maketype("$boolean", 0L, 1L); t_int = maketype("$integer", 0x80000000L, 0x7fffffffL); t_char = maketype("$char", 0L, 255L); t_real = maketype("$real", 8L, 0L); t_nil = maketype("$nil", 0L, 0L); t_addr = insert(identname("$address", true)); t_addr->language = primlang; t_addr->level = 0; t_addr->class = TYPE; t_addr->type = newSymbol(nil, 1, PTR, t_int, nil); s = insert(identname("true", true)); s->class = CONST; s->type = t_boolean; s->symvalue.constval = build(O_LCON, 1L); s->symvalue.constval->nodetype = t_boolean; s = insert(identname("false", true)); s->class = CONST; s->type = t_boolean; s->symvalue.constval = build(O_LCON, 0L); s->symvalue.constval->nodetype = t_boolean; /* Create vector register element type */ if(vectorcapable) { t_vmr = maketype("$vmr", 0L, 1L); t_vquad = maketype("$vquad", 8L, 0L); t_vfloat = maketype("vfloat", 8L, 0L); t_vhex = maketype("vhex", 8L, 0L); t_vint = maketype("vint", 8L, 0L); }}/* * Reduce type to avoid worrying about type names. */public Symbol rtype(type)Symbol type;{ register Symbol t; t = type; if (t != nil) { if (t->class == VAR or t->class == CONST or t->class == FIELD or t->class == REF ) { assert(t != t->type); t = t->type; } if (t->class == TYPEREF) { resolveRef(t); } while (t->class == TYPE or t->class == TAG) { assert(t != t->type); t = t->type; if (t->class == TYPEREF) { resolveRef(t); } } } return t;}/* * Find the end of a module name. Return nil if there is none * in the given string. */private String findModuleMark (s)String s;{ register char *p, *r; register boolean done; p = s; done = false; do { if (*p == ':') { done = true; r = p; } else if (*p == '\0') { done = true; r = nil; } else { ++p; } } while (not done); return r;}/* * Resolve a type reference by modifying to be the appropriate type. * * If the reference has a name, then it refers to an opaque type and * the actual type is directly accessible. Otherwise, we must use * the type reference string, which is of the form "module:{module:}name". */public resolveRef (t)Symbol t;{ register char *p; char *start; Symbol s, m, outer; Name n; if (t->name != nil) { s = t; } else { start = t->symvalue.typeref; outer = program; p = findModuleMark(start); while (p != nil) { *p = '\0'; n = identname(start, true); find(m, n) where m->block == outer endfind(m); if (m == nil) { p = nil; outer = nil; s = nil; } else { outer = m; start = p + 1; p = findModuleMark(start); } } if (outer != nil) { n = identname(start, true); find(s, n) where s->block == outer endfind(s); } } if (s != nil and s->type != nil) { t->name = s->type->name; t->class = s->type->class; t->type = s->type->type; t->chain = s->type->chain; t->symvalue = s->type->symvalue; t->block = s->type->block; }}public integer regnum (s)Symbol s;{ integer r; checkref(s); if (s->level < 0) { r = s->symvalue.offset; } else { r = -1; } return r;}public Symbol container(s)Symbol s;{ checkref(s); return s->block;}public Node constval(s)Symbol s;{ checkref(s); if (s->class != CONST) { error("[internal error: constval(non-CONST)]"); } return s->symvalue.constval;}/* * Return the object address of the given symbol. * * There are the following possibilities: * * globals - just take offset * locals - take offset from locals base * arguments - take offset from argument base * register - offset is register number
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -