📄 stabstring.c
字号:
enterblock(s); } if (class != MODULE) { s->symvalue.funcv.src = true; } curparam = s;}/* * Handling an external variable is tricky, since we might already * know it but need to define it's type for other type information * in the file. So just in case we read the type information anyway. */private extVar (symp, n, off)Symbol *symp;Name n;integer off;{ Symbol s, t; find(s, n) where s->level == program->level and s->class == VAR endfind(s); if (s == nil) { makeVariable(s, n, off); s->level = program->level; s->block = curmodule; getExtRef(s); } else { t = constype(nil); } *symp = s;}/* * Check to see if the stab string contains the name of the external * reference. If so, we create a symbol with that name and class EXTREF, and * connect it to the given symbol. This link is created so that when * we see the linker symbol we can resolve it to the given symbol. */private getExtRef (s)Symbol s;{ char *p; Name n; Symbol t; if (*curchar == ',' and *(curchar + 1) != '\0') { p = index(curchar + 1, ','); *curchar = '\0'; if (p != nil) { *p = '\0'; n = identname(curchar + 1, false); curchar = p + 1; } else { n = identname(curchar + 1, true); } t = insert(n); t->language = s->language; t->class = EXTREF; t->block = program; t->level = program->level; t->symvalue.extref = s; }}/* * Find a block with the given identifier in the given outer block. * If not there, then create it. */private Symbol findBlock (id, m)String id;Symbol m;{ Name n; Symbol s; n = identname(id, true); find(s, n) where s->block == m and isblock(s) endfind(s); if (s == nil) { s = insert(n); s->block = m; s->language = curlang; s->class = MODULE; s->level = m->level + 1; } return s;}/* * Enter a nested block. * The block within which it is nested is described * by "module{:module}[:proc]". */private enterNestedBlock (b)Symbol b;{ register char *p, *q; Symbol m, s; Name n; q = curchar; p = index(q, ':'); m = program; while (p != nil) { *p = '\0'; m = findBlock(q, m); q = p + 1; p = index(q, ':'); } if (*q != '\0') { m = findBlock(q, m); } b->level = m->level + 1; b->block = m; pushBlock(b);}/* * Enter a statically-allocated variable defined within a routine. * * Global BSS variables are chained together so we can resolve them * when the start of common is determined. The list is kept in order * so that f77 can display all vars in a COMMON. */private ownVariable (s, addr)Symbol s;Address addr;{ s->level = 1; if (curcomm) { if (commchain != nil) { commchain->symvalue.common.chain = s; } else { curcomm->symvalue.common.offset = (integer) s; } commchain = s; s->symvalue.common.offset = addr; s->symvalue.common.chain = nil; }}/* * Get a type from the current stab string for the given symbol. */private getType (s)Symbol s;{ s->type = constype(nil); if (s->class == TAG) { addtag(s); }}/* * Construct a type out of a string encoding. * * The forms of the string are * * <number> * <number>=<type> * r<type>;<number>;<number> -- subrange * a<type>;<type> -- array[index] of element * A<type> -- open array * s<size>{<name>:<type>;<number>;<number>}-- record * u<size>{<name>:<type>;<number>;<number>}-- union * *<type> -- pointer * f<type>,<integer>;<paramlist> -- function variable * p<integer>;<paramlist> -- procedure variable * S<type> -- set of type * o<name>[,<type>] -- opaque type * i<name>,<type> -- imported type */private Rangetype getRangeBoundType();private Symbol constype (type)Symbol type;{ register Symbol t; register integer n; char class; char *p; while (*curchar == '@') { p = index(curchar, ';'); if (p == nil) { fflush(stdout); fprintf(stderr, "missing ';' after type attributes"); } else { curchar = p + 1; } } if (isdigit(*curchar)) { n = getint(); if (n >= NTYPES) { panic("too many types in file \"%s\"", curfilename()); } if (*curchar == '=') { if (typetable[n] != nil) { t = typetable[n]; } else { t = symbol_alloc(); typetable[n] = t; } ++curchar; constype(t); } else { t = typetable[n]; if (t == nil) { t = symbol_alloc(); typetable[n] = t; } } } else { if (type == nil) { t = symbol_alloc(); } else { t = type; } t->language = curlang; t->level = curblock->level + 1; t->block = curblock; class = *curchar++; switch (class) { case T_SUBRANGE: consSubrange(t); break; case T_ARRAY: t->class = ARRAY; t->chain = constype(nil); skipchar(curchar, ';'); chkcont(curchar); t->type = constype(nil); break; case T_OLDOPENARRAY: t->class = DYNARRAY; t->symvalue.ndims = 1; t->type = constype(nil); t->chain = t_int; break; case T_OPENARRAY: case T_DYNARRAY: consDynarray(t); break; case T_SUBARRAY: t->class = SUBARRAY; t->symvalue.ndims = getint(); skipchar(curchar, ','); t->type = constype(nil); t->chain = t_int; break; case T_RECORD: consRecord(t, RECORD); break; case T_UNION: consRecord(t, VARNT); break; case T_ENUM: consEnum(t); break; case T_PTR: t->class = PTR; t->type = constype(nil); break; /* * C function variables are different from Modula-2's. */ case T_FUNCVAR: t->class = FFUNC; t->type = constype(nil); if (curlang != findlanguage(C)) { skipchar(curchar, ','); consParamlist(t); } break; case T_PROCVAR: t->class = FPROC; consParamlist(t); break; case T_IMPORTED: consImpType(t); break; case T_SET: t->class = SET; t->type = constype(nil); break; case T_OPAQUE: consOpaqType(t); break; case T_FILE: t->class = FILET; t->type = constype(nil); break; default: badcaseval(class); } } return t;}/* * Construct a subrange type. */private consSubrange (t)Symbol t;{ t->class = RANGE; t->type = constype(nil); skipchar(curchar, ';'); chkcont(curchar); t->symvalue.rangev.lowertype = getRangeBoundType(); t->symvalue.rangev.lower = getint(); skipchar(curchar, ';'); chkcont(curchar); t->symvalue.rangev.uppertype = getRangeBoundType(); t->symvalue.rangev.upper = getint();}/* * Figure out the bound type of a range. * * Some letters indicate a dynamic bound, ie what follows * is the offset from the fp which contains the bound; this will * need a different encoding when pc a['A'..'Z'] is * added; J is a special flag to handle fortran a(*) bounds */private Rangetype getRangeBoundType (){ Rangetype r; switch (*curchar) { case 'A': r = R_ARG; curchar++; break; case 'T': r = R_TEMP; curchar++; break; case 'J': r = R_ADJUST; curchar++; break; default: r = R_CONST; break; } return r;}/* * Construct a dynamic array descriptor. */private consDynarray (t)register Symbol t;{ t->class = DYNARRAY; t->symvalue.ndims = getint(); skipchar(curchar, ','); t->type = constype(nil); t->chain = t_int;}/* * Construct a record or union type. */private consRecord (t, class)Symbol t;Symclass class;{ register Symbol u; register char *cur, *p; Name name; integer d; t->class = class; t->symvalue.offset = getint(); d = curblock->level + 1; u = t; cur = curchar; while (*cur != ';' and *cur != '\0') { p = index(cur, ':'); if (p == nil) { panic("index(\"%s\", ':') failed", curchar); } *p = '\0'; name = identname(cur, true); u->chain = newSymbol(name, d, FIELD, nil, nil); cur = p + 1; u = u->chain; u->language = curlang; curchar = cur; u->type = constype(nil); skipchar(curchar, ','); u->symvalue.field.offset = getint(); skipchar(curchar, ','); u->symvalue.field.length = getint(); skipchar(curchar, ';'); chkcont(curchar); cur = curchar; } if (*cur == ';') { ++cur; } curchar = cur;}/* * Construct an enumeration type. */private consEnum (t)Symbol t;{ register Symbol u; register char *p; register integer count; t->class = SCAL; count = 0; u = t; while (*curchar != ';' and *curchar != '\0') { p = index(curchar, ':'); assert(p != nil); *p = '\0'; u->chain = insert(identname(curchar, true)); curchar = p + 1; u = u->chain; u->language = curlang; u->class = CONST; u->level = curblock->level + 1; u->block = curblock; u->type = t; u->symvalue.constval = build(O_LCON, (long) getint()); ++count; skipchar(curchar, ','); chkcont(curchar); } if (*curchar == ';') { ++curchar; } t->symvalue.iconval = count;}/* * Construct a parameter list for a function or procedure variable. */private consParamlist (t)Symbol t;{ Symbol p; integer i, d, n, paramclass; n = getint(); skipchar(curchar, ';'); p = t; d = curblock->level + 1; for (i = 0; i < n; i++) { p->chain = newSymbol(nil, d, VAR, nil, nil); p = p->chain; p->type = constype(nil); skipchar(curchar, ','); paramclass = getint(); if (paramclass == 0) { p->class = REF; } skipchar(curchar, ';'); chkcont(curchar); }}/* * Construct an imported type. * Add it to a list of symbols to get fixed up. */private consImpType (t)Symbol t;{ register char *p; Symbol tmp; p = curchar; while (*p != ',' and *p != ';' and *p != '\0') { ++p; } if (*p == '\0') { panic("bad import symbol entry '%s'", curchar); } t->class = TYPEREF; t->symvalue.typeref = curchar; if (*p == ',') { curchar = p + 1; tmp = constype(nil); } else { curchar = p; } skipchar(curchar, ';'); *p = '\0';}/* * Construct an opaque type entry. */private consOpaqType (t)Symbol t;{ register char *p; register Symbol s; register Name n; boolean def; p = curchar; while (*p != ';' and *p != ',') { if (*p == '\0') { panic("bad opaque symbol entry '%s'", curchar); } ++p; } def = (Boolean) (*p == ','); *p = '\0'; n = identname(curchar, true); find(s, n) where s->class == TYPEREF endfind(s); if (s == nil) { s = insert(n); s->class = TYPEREF; s->type = nil; } curchar = p + 1; if (def) { s->type = constype(nil); skipchar(curchar, ';'); } t->class = TYPE; t->type = s;}/* * Read an integer from the current position in the type string. */private integer getint (){ register integer n; register char *p; register Boolean isneg; n = 0; p = curchar; if (*p == '-') { isneg = true; ++p; } else { isneg = false; } while (isdigit(*p)) { n = 10*n + (*p - '0'); ++p; } curchar = p; return isneg ? (-n) : n;}/* * Add a tag name. This is a kludge to be able to refer * to tags that have the same name as some other symbol * in the same block. */private addtag (s)register Symbol s;{ register Symbol t; char buf[100]; sprintf(buf, "$$%.90s", ident(s->name)); t = insert(identname(buf, false)); t->language = s->language; t->class = TAG; t->type = s->type; t->block = s->block;}/* Routine to handle VAX Debug DST types that will not map to a specific * stab entry. Keep the name around, and assign a special class, so that * we are able to acknowledge the existence of the symbol (ie, don't * give "undefined" error message). In which() (symbols.c), if one of * these is encountered, we print a message saying that symbolic information * is not available for the symbol. */public mkdstsym(name)String name;{ Symbol s; Name n; n = identname(name, true); newSym(s, n); s->class = NO_DSTMAP;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -