void dumpsyms(Stab *st, int indent) { size_t i, n; void **k; /* decls */ k = htkeys(st->dcl, &n); for (i = 0; i < n; i++) { dumptypes(getdcl(st, k[i]), indent); } free(k); /* union constructors */ k = htkeys(st->uc, &n); for (i = 0; i < n; i++) dumpucon(getucon(st, k[i]), indent + 1); /* sub-namespaces */ k = htkeys(st->ns, &n); for (i = 0; i < n; i++) { printindent(indent + 1); printf("namespace %s:\n", (char*)k[i]); dumpsyms(getns_str(st, k[i]), indent + 2); } free(k); }
/* Outputs a symbol table, and it's sub-tables * recursively, with a sigil describing the symbol * type, as follows: * T type * S symbol * N namespace * * Does not print captured variables. */ static void outstab(Stab *st, FILE *fd, int depth) { size_t i, n; char *name; void **k; char *ty; Type *t; name = ""; if (st->name) name = st->name; findentf(fd, depth, "Stab %p (super = %p, name=\"%s\")\n", st, st->super, name); if (!st) return; /* print types */ k = htkeys(st->ty, &n); for (i = 0; i < n; i++) { findentf(fd, depth + 1, "T "); /* already indented */ outname(k[i], fd); t = gettype(st, k[i]); if (t->nsub) ty = tystr(t->sub[0]); else ty = strdup("none"); fprintf(fd, " = %s [tid=%d]\n", ty, t->tid); free(ty); } free(k); /* dump declarations */ k = htkeys(st->dcl, &n); for (i = 0; i < n; i++) { findentf(fd, depth + 1, "S "); /* already indented */ outsym(getdcl(st, k[i]), fd, 0); } free(k); /* dump closure */ if (st->env) { k = htkeys(st->env, &n); for (i = 0; i < n; i++) { findentf(fd, depth + 1, "U "); /* already indented */ outsym(getclosed(st, k[i]), fd, 0); } free(k); } }
/* Outputs a symbol table, and it's sub-tables * recursively, with a sigil describing the symbol * type, as follows: * T type * S symbol * N namespace * * Does not print captured variables. */ static void outstab(Stab *st, FILE *fd, int depth) { size_t i, n; void **k; char *ty; Type *t; indent(fd, depth); fprintf(fd, "Stab %p (super = %p, name=\"%s\")\n", st, st->super, namestr(st->name)); if (!st) return; /* print types */ k = htkeys(st->ty, &n); for (i = 0; i < n; i++) { indent(fd, depth + 1); fprintf(fd, "T "); /* already indented */ outname(k[i], fd); t = gettype(st, k[i]); ty = tystr(t); fprintf(fd, " = %s [tid=%d]\n", ty, t->tid); free(ty); } free(k); /* dump declarations */ k = htkeys(st->dcl, &n); for (i = 0; i < n; i++) { indent(fd, depth + 1); fprintf(fd, "S "); /* already indented */ outsym(getdcl(st, k[i]), fd, 0); } free(k); /* dump sub-namespaces */ k = htkeys(st->ns, &n); for (i = 0; i < n; i++) { indent(fd, depth + 1); fprintf(fd, "N %s\n", (char*)k[i]); outstab(getns_str(st, k[i]), fd, depth + 1); } free(k); }
void dumpfilestabs(Node *file, int depth, FILE *fd) { size_t nk, i; void **k; k = htkeys(file->file.ns, &nk); for (i = 0; i < nk; i++) { outstab(htget(file->file.ns, k[i]), fd, depth); } free(k); }
void genstrings(FILE *fd, Htab *strtab) { void **k; Str *s; size_t i, nk; k = htkeys(strtab, &nk); for (i = 0; i < nk; i++) { s = k[i]; fprintf(fd, "%s:\n", (char*)htget(strtab, k[i])); writebytes(fd, s->buf, s->len); } }
/* Outputs a symbol table to file in a way that can be * read back usefully. Only writes declarations, types * and sub-namespaces. Captured variables are ommitted. */ static void wrstab(FILE *fd, Stab *val) { size_t n, i; void **keys; wrstr(fd, val->name); /* write decls */ keys = htkeys(val->dcl, &n); wrint(fd, n); for (i = 0; i < n; i++) wrsym(fd, getdcl(val, keys[i])); free(keys); /* write types */ keys = htkeys(val->ty, &n); wrint(fd, n); for (i = 0; i < n; i++) { pickle(fd, keys[i]); /* name */ wrtype(fd, gettype(val, keys[i])); /* type */ } free(keys); }
static void genstrings(FILE *fd, Htab *strtab) { void **k; char *lbl; Str *s; size_t i, nk; k = htkeys(strtab, &nk); for (i = 0; i < nk; i++) { s = k[i]; lbl = htget(strtab, k[i]); if (s->len) { fprintf(fd, "GLOBL %s+0(SB),$%lld\n", lbl, (vlong)s->len); writebytes(fd, lbl, 0, s->buf, s->len); } } }
/* Usefile format: * U<pkgname> * L<liblist> * I<initlist> * T<pickled-type> * D<picled-decl> * G<pickled-decl><pickled-initializer> * Z */ void writeuse(FILE *f, Node *file) { Stab *st; void **k; Node *s, *u; size_t i, n; assert(file->type == Nfile); st = file->file.globls; /* usefile name */ wrbyte(f, 'U'); wrint(f, Abiversion); /* use version */ if (st->name) wrstr(f, st->name); else wrstr(f, NULL); /* library deps */ for (i = 0; i < file->file.nuses; i++) { u = file->file.uses[i]; if (!u->use.islocal) { wrbyte(f, 'L'); wrstr(f, u->use.name); } } for (i = 0; i < file->file.nlibdeps; i++) { wrbyte(f, 'L'); wrstr(f, file->file.libdeps[i]); } for (i = 0; i < file->file.nextlibs; i++) { wrbyte(f, 'X'); wrstr(f, file->file.extlibs[i]); } /* source file name */ wrbyte(f, 'F'); wrstr(f, file->file.files[0]); for (i = 0; i < ntypes; i++) { if (types[i]->vis == Visexport || types[i]->vis == Vishidden) { wrbyte(f, 'T'); wrint(f, types[i]->tid); typickle(f, types[i]); } } for (i = 0; i < ntraittab; i++) { if (traittab[i]->vis == Visexport || traittab[i]->vis == Vishidden) { wrbyte(f, 'R'); traitpickle(f, traittab[i]); } } k = htkeys(st->impl, &n); for (i = 0; i < n; i++) { /* merging during inference should remove all protos */ s = getimpl(st, k[i]); assert(!s->impl.isproto); if (s->impl.vis == Visexport || s->impl.vis == Vishidden) { wrbyte(f, 'I'); pickle(f, s); } } free(k); k = htkeys(st->dcl, &n); for (i = 0; i < n; i++) { s = getdcl(st, k[i]); assert(s != NULL); if (s->decl.vis == Visintern || s->decl.vis == Visbuiltin) continue; /* trait functions get written out with their traits */ if (s->decl.trait || s->decl.isinit) continue; else if (s->decl.isgeneric) wrbyte(f, 'G'); else wrbyte(f, 'D'); wrsym(f, s); } for (i = 0; i < file->file.ninit; i++) { wrbyte(f, 'S'); pickle(f, file->file.init[i]); } if (file->file.localinit) { wrbyte(f, 'S'); pickle(f, file->file.localinit->decl.name); } free(k); }