- register char *p;
- register int c;
- register Name n;
- register Integer i;
- Boolean knowtype, isnew;
- Symclass class;
- Integer level;
-
- p = index(str, ':');
- *p = '\0';
- c = *(p+1);
- n = identname(str, true);
- if (index("FfGV", c) != nil) {
- if (c == 'F' or c == 'f') {
- class = FUNC;
- } else {
- class = VAR;
- }
- level = (c == 'f' ? curmodule->level : program->level);
- find(s, n) where s->level == level and s->class == class endfind(s);
- if (s == nil) {
- isnew = true;
- s = insert(n);
- } else {
- isnew = false;
- }
- } else {
- isnew = true;
- s = insert(n);
- }
-
- /*
- * Default attributes.
- */
- s->language = curlang;
- s->class = VAR;
- s->block = curblock;
- s->level = curlevel;
- s->symvalue.offset = np->n_value;
- curchar = p + 2;
- knowtype = false;
- switch (c) {
- case 't': /* type name */
- s->class = TYPE;
- i = getint();
- if (i == 0) {
- panic("bad input on type \"%s\" at \"%s\"", symname(s),
- curchar);
- } else if (i >= NTYPES) {
- panic("too many types in file \"%s\"", curfilename());
- }
- /*
- * A hack for C typedefs that don't create new types,
- * e.g. typedef unsigned int Hashvalue;
- * or typedef struct blah BLAH;
- */
- if (*curchar == '\0') {
- s->type = typetable[i];
- if (s->type == nil) {
- s->type = symbol_alloc();
- typetable[i] = s->type;
- }
- knowtype = true;
- } else {
- typetable[i] = s;
- skipchar(curchar, '=');
- }
- break;
-
- case 'T': /* tag */
- s->class = TAG;
- i = getint();
- if (i == 0) {
- panic("bad input on tag \"%s\" at \"%s\"", symname(s),
- curchar);
- } else if (i >= NTYPES) {
- panic("too many types in file \"%s\"", curfilename());
- }
- if (typetable[i] != nil) {
- typetable[i]->language = curlang;
- typetable[i]->class = TYPE;
- typetable[i]->type = s;
- } else {
- typetable[i] = s;
- }
- skipchar(curchar, '=');
- break;
-
- case 'F': /* public function */
- case 'f': /* private function */
- s->class = FUNC;
- if (curblock->class == FUNC or curblock->class == PROC) {
- exitblock();
- }
- enterblock(s);
- if (c == 'F') {
- s->level = program->level;
- isnew = false;
- }
- curparam = s;
- if (isnew) {
- s->symvalue.funcv.src = false;
- s->symvalue.funcv.beginaddr = np->n_value;
- newfunc(s);
- findbeginning(s);
- }
- break;
-
- case 'G': /* public variable */
- s->level = program->level;
- break;
-
- case 'S': /* private variable */
- s->level = curmodule->level;
- s->block = curmodule;
- break;
-
-/*
- * keep global BSS variables chained so can resolve when get the start
- * of common; keep the list in order so f77 can display all vars in a COMMON
-*/
- case 'V': /* own variable */
- s->level = 2;
- if (curcomm) {
- if (commchain != nil) {
- commchain->symvalue.common.chain = s;
- }
- else {
- curcomm->symvalue.common.offset = (int) s;
- }
- commchain = s;
- s->symvalue.common.offset = np->n_value;
- s->symvalue.common.chain = nil;
- }
- break;
-
- case 'r': /* register variable */
- s->level = -(s->level);
- break;
-
- case 'p': /* parameter variable */
- curparam->chain = s;
- curparam = s;
- break;
-
- case 'v': /* varies parameter */
- s->class = REF;
- s->symvalue.offset = np->n_value;
- curparam->chain = s;
- curparam = s;
- break;
-
- default: /* local variable */
- --curchar;
- break;
- }
- if (not knowtype) {
- s->type = constype(nil);
- if (s->class == TAG) {
- addtag(s);
- }
- }
- if (tracesyms) {
- printdecl(s);
- fflush(stdout);