diff options
Diffstat (limited to 'src/old/c/export.c')
-rw-r--r-- | src/old/c/export.c | 585 |
1 files changed, 585 insertions, 0 deletions
diff --git a/src/old/c/export.c b/src/old/c/export.c new file mode 100644 index 000000000..de54f1fe3 --- /dev/null +++ b/src/old/c/export.c @@ -0,0 +1,585 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#include "go.h" +#include "y.tab.h" + +void +markexport(Node *n) +{ + Sym *s; + Dcl *d, *r; + +loop: + if(n == N) + return; + if(n->op == OLIST) { + markexport(n->left); + n = n->right; + goto loop; + } + if(n->op != OEXPORT) + fatal("markexport: op no OEXPORT: %O", n->op); + + s = n->sym; + if(n->psym != S) + s = pkglookup(n->sym->name, n->psym->name); + + if(s->export != 0) + return; + s->export = 1; + + d = mal(sizeof(*d)); + d->dsym = s; + d->dnode = N; + d->lineno = curio.lineno; + + r = exportlist; + d->back = r->back; + r->back->forw = d; + r->back = d; +} + +void +reexport(Node *t) +{ + Sym *s; + + if(t == N) + fatal("reexport: type nil\n"); + + s = t->sym; + if(s == S/* || s->name[0] == '_'*/) { + exportgen++; + snprint(namebuf, sizeof(namebuf), "_e%.3ld", exportgen); + s = lookup(namebuf); + s->lexical = LATYPE; + s->otype = t; + t->sym = s; + } + dumpexporttype(s); +} + +void +dumpexportconst(Sym *s) +{ + Node *n, *t; + + if(s->exported != 0) + return; + s->exported = 1; + + n = s->oconst; + if(n == N || n->op != OLITERAL) + fatal("dumpexportconst: oconst nil: %S\n", s); + + t = n->type; // may or may not be specified + if(t != N) + reexport(t); + + Bprint(bout, "\tconst "); + if(s->export != 0) + Bprint(bout, "!"); + Bprint(bout, "%lS ", s); + if(t != N) + Bprint(bout, "%lS ", t->sym); + + switch(n->val.ctype) { + default: + fatal("dumpexportconst: unknown ctype: %S\n", s); + case CTINT: + case CTSINT: + case CTUINT: + case CTBOOL: + Bprint(bout, "0x%llux\n", n->val.vval); + break; + case CTFLT: + Bprint(bout, "%.17e\n", n->val.dval); + break; + case CTSTR: + Bprint(bout, "\"%Z\"\n", n->val.sval); + break; + } +} + +void +dumpexportvar(Sym *s) +{ + Node *n, *t; + + if(s->exported != 0) + return; + s->exported = 1; + + n = s->oname; + if(n == N || n->type == N) + fatal("dumpexportvar: oname nil: %S\n", s); + + t = n->type; + reexport(t); + + Bprint(bout, "\tvar "); + if(s->export != 0) + Bprint(bout, "!"); + Bprint(bout, "%lS %lS\n", s, t->sym); +} + +void +dumpexporttype(Sym *s) +{ + Node *t, *f; + Sym *ts; + int et; + + if(s->exported != 0) + return; + s->exported = 1; + + t = s->otype; + if(t == N || t->op != OTYPE) + fatal("dumpexporttype: otype nil: %S\n", s); + if(t->sym != s) + fatal("dumpexporttype: cross reference: %S\n", s); + + et = t->etype; + switch(et) { + default: + if(et < 0 || et >= nelem(types) || types[et] == N) + fatal("dumpexporttype: basic type: %E\n", et); + /* type 5 */ + Bprint(bout, "\ttype %lS %d\n", s, et); + break; + + case TARRAY: + reexport(t->type); + + /* type 2 */ + Bprint(bout, "\ttype "); + if(s->export != 0) + Bprint(bout, "!"); + Bprint(bout, "%lS [%lud] %lS\n", s, t->bound, t->type->sym); + break; + + case TPTR: + reexport(t->type); + + /* type 6 */ + Bprint(bout, "\ttype "); + if(s->export != 0) + Bprint(bout, "!"); + Bprint(bout, "%lS *%lS\n", s, t->type->sym); + break; + + case TFUNC: + for(f=t->type; f!=N; f=f->down) { + if(f->op != OTYPE || f->etype != TSTRUCT) + fatal("dumpexporttype: funct not field: %O/%E\n", + f->op, f->etype); + reexport(f); + } + + /* type 3 */ + Bprint(bout, "\ttype "); + if(s->export != 0) + Bprint(bout, "!"); + Bprint(bout, "%lS (", s); + for(f=t->type; f!=N; f=f->down) { + if(f != t->type) + Bprint(bout, " "); + Bprint(bout, "%lS", f->sym); + } + Bprint(bout, ")\n"); + break; + + case TSTRUCT: + case TINTER: + for(f=t->type; f!=N; f=f->down) { + if(f->op != OTYPE || f->etype != TFIELD) + fatal("dumpexporttype: funct not field: %O/%E\n", + f->op, f->etype); + reexport(f->type); + } + + /* type 4 */ + Bprint(bout, "\ttype "); + if(s->export) + Bprint(bout, "!"); + Bprint(bout, "%lS %c", s, (et==TSTRUCT)? '{': '<'); + for(f=t->type; f!=N; f=f->down) { + ts = f->type->sym; + if(f != t->type) + Bprint(bout, " "); + Bprint(bout, "%s %lS", f->sym->name, ts); + } + Bprint(bout, "%c\n", (et==TSTRUCT)? '}': '>'); + break; + } +} + +void +dumpe(Sym *s) +{ + switch(s->lexical) { + default: + yyerror("unknown export symbol: %S\n", s, s->lexical); + break; + case LPACK: + yyerror("package export symbol: %S\n", s); + break; + case LATYPE: + case LBASETYPE: + dumpexporttype(s); + break; + case LNAME: + dumpexportvar(s); + break; + case LACONST: + dumpexportconst(s); + break; + } +} + +void +dumpexport(void) +{ + Dcl *d; + long lno; + + lno = dynlineno; + + Bprint(bout, " import\n"); + Bprint(bout, " ((\n"); + + // print it depth first + for(d=exportlist->forw; d!=D; d=d->forw) { + dynlineno = d->lineno; + dumpe(d->dsym); + } + + Bprint(bout, " ))\n"); + + dynlineno = lno; +} + +/* + * ******* import ******* + */ +Node* +importlooktype(Node *n) +{ + Sym *s; + + if(n->op != OIMPORT) + fatal("importlooktype: oops1 %N\n", n); + + s = pkglookup(n->sym->name, n->psym->name); + if(s->otype == N) + fatal("importlooktype: oops2 %S\n", s); + + return s->otype; +} + +Node** +importstotype(Node *n, Node **t, Node *uber) +{ + Node *f; + Iter save; + + n = listfirst(&save, &n); + +loop: + if(n == N) { + *t = N; + return t; + } + + f = nod(OTYPE, N, N); + f->etype = TFIELD; + f->type = importlooktype(n); + f->uberstruct = uber; + + if(n->fsym != S) { + f->nname = newname(n->fsym); + } else { + vargen++; + snprint(namebuf, sizeof(namebuf), "_m%.3ld", vargen); + f->nname = newname(lookup(namebuf)); + } + f->sym = f->nname->sym; + f->nname->uberstruct = uber; + + *t = f; + t = &f->down; + + n = listnext(&save); + goto loop; +} + +int +importcount(Node *t) +{ + int i; + Node *f; + + if(t == N || t->op != OTYPE || t->etype != TSTRUCT) + fatal("importcount: not a struct: %N", t); + + i = 0; + for(f=t->type; f!=N; f=f->down) + i = i+1; + return i; +} + +void +importfuncnam(Node *t) +{ + Node *n, *n1; + + if(t->etype != TFUNC) + fatal("importfuncnam: not func %T\n", t); + + if(t->thistuple > 0) { + n1 = t->type; + if(n1->sym == S) + fatal("importfuncnam: no this"); + n = newname(n1->sym); + vargen++; + n->vargen = vargen; + n1->nname = n; + } + if(t->outtuple > 0) { + n1 = t->type->down; + if(n1->sym == S) + fatal("importfuncnam: no output"); + n = newname(n1->sym); + vargen++; + n->vargen = vargen; + n1->nname = n; + } + if(t->intuple > 0) { + n1 = t->type->down->down; + if(n1->sym == S) + fatal("importfuncnam: no input"); + n = newname(n1->sym); + vargen++; + n->vargen = vargen; + n1->nname = n; + } +} + +Sym* +getimportsym(Node *ss) +{ + char *pkg; + Sym *s; + + pkg = ss->psym->name; + if(ss->kaka) { + pkg = package; + if(pkgmyname != S) + pkg = pkgmyname->name; + } + s = pkglookup(ss->sym->name, pkg); + /* botch - need some diagnostic checking for the following assignment */ + s->opackage = ss->osym->name; + return s; +} + +void +importaddtyp(Node *ss, Node *t) +{ + Sym *s; + + s = getimportsym(ss); + if(s->otype == N || !eqtype(t, s->otype, 0)) { + addtyp(newtype(s), t, PEXTERN); + } +} + +/* + * LCONST importsym LITERAL + * untyped constant + */ +void +doimportc1(Node *ss, Val *v) +{ + Node *n; + Sym *s; + + n = nod(OLITERAL, N, N); + n->val = *v; + + s = getimportsym(ss); + if(s->oconst == N) { + // botch sould ask if already declared the same + dodclconst(newname(s), n); + } +} + +/* + * LCONST importsym importsym LITERAL + * typed constant + */ +void +doimportc2(Node *ss, Node *st, Val *v) +{ + Node *n, *t; + Sym *s; + + n = nod(OLITERAL, N, N); + n->val = *v; + + t = importlooktype(st); + n->type = t; + + s = getimportsym(ss); + if(s->oconst == N) { + // botch sould ask if already declared the same + dodclconst(newname(s), n); + } +} + +/* + * LVAR importsym importsym + * variable + */ +void +doimportv1(Node *ss, Node *st) +{ + Node *t; + Sym *s; + + t = importlooktype(st); + s = getimportsym(ss); + if(s->oname == N || !eqtype(t, s->oname->type, 0)) { + addvar(newname(s), t, dclcontext); + } +} + +/* + * LTYPE importsym [ importsym ] importsym + * array type + */ +void +doimport1(Node *ss, Node *ss1, Node *s) +{ + fatal("doimport1"); +} + +/* + * LTYPE importsym [ LLITERAL ] importsym + * array type + */ +void +doimport2(Node *ss, Val *b, Node *st) +{ + Node *t; + Sym *s; + + t = nod(OTYPE, N, N); + t->etype = TARRAY; + t->bound = b->vval; + s = pkglookup(st->sym->name, st->psym->name); + t->type = s->otype; + + importaddtyp(ss, t); +} + +/* + * LTYPE importsym '(' importsym_list ')' + * function/method type + */ +void +doimport3(Node *ss, Node *n) +{ + Node *t; + + t = nod(OTYPE, N, N); + t->etype = TFUNC; + + t->type = importlooktype(n->left); + t->type->down = importlooktype(n->right->left); + t->type->down->down = importlooktype(n->right->right); + + t->thistuple = importcount(t->type); + t->outtuple = importcount(t->type->down); + t->intuple = importcount(t->type->down->down); + + importfuncnam(t); + + importaddtyp(ss, t); +} + +/* + * LTYPE importsym '{' importsym_list '}' + * structure type + */ +void +doimport4(Node *ss, Node *n) +{ + Node *t; + + t = nod(OTYPE, N, N); + t->etype = TSTRUCT; + importstotype(n, &t->type, t); + + importaddtyp(ss, t); +} + +/* + * LTYPE importsym LLITERAL + * basic type + */ +void +doimport5(Node *ss, Val *v) +{ + int et; + Node *t; + + et = v->vval; + if(et <= 0 || et >= nelem(types) || types[et] == N) + fatal("doimport5: bad type index: %E\n", et); + + t = nod(OTYPE, 0, 0); + t->etype = et; + t->sym = S; + + importaddtyp(ss, t); +} + +/* + * LTYPE importsym * importsym + * pointer type + */ +void +doimport6(Node *ss, Node *st) +{ + Node *t; + Sym *s; + + s = pkglookup(st->sym->name, st->psym->name); + t = s->otype; + if(t == N) + t = forwdcl(s); + else + t = ptrto(t); + + importaddtyp(ss, t); +} + +/* + * LTYPE importsym '<' importsym '>' + * interface type + */ +void +doimport7(Node *ss, Node *n) +{ + Node *t; + + t = nod(OTYPE, N, N); + t->etype = TINTER; + importstotype(n, &t->type, t); + + importaddtyp(ss, t); +} |