2008-06-04 15:37:38 -06:00
|
|
|
// 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.
|
|
|
|
|
2011-08-25 14:25:10 -06:00
|
|
|
#include <u.h>
|
|
|
|
#include <libc.h>
|
2008-06-04 15:37:38 -06:00
|
|
|
#include "go.h"
|
|
|
|
#include "y.tab.h"
|
|
|
|
|
2011-12-14 07:05:33 -07:00
|
|
|
static void dumpexporttype(Type *t);
|
2008-06-04 15:37:38 -06:00
|
|
|
|
2011-12-05 12:40:19 -07:00
|
|
|
// Mark n's symbol as exported
|
2008-09-26 22:27:26 -06:00
|
|
|
void
|
2009-08-04 23:59:23 -06:00
|
|
|
exportsym(Node *n)
|
2008-09-26 22:27:26 -06:00
|
|
|
{
|
2009-08-04 23:59:23 -06:00
|
|
|
if(n == N || n->sym == S)
|
2008-09-26 22:27:26 -06:00
|
|
|
return;
|
2009-08-04 23:59:23 -06:00
|
|
|
if(n->sym->flags & (SymExport|SymPackage)) {
|
|
|
|
if(n->sym->flags & SymPackage)
|
|
|
|
yyerror("export/package mismatch: %S", n->sym);
|
2008-09-26 22:27:26 -06:00
|
|
|
return;
|
2008-11-14 17:35:08 -07:00
|
|
|
}
|
2009-08-04 23:59:23 -06:00
|
|
|
n->sym->flags |= SymExport;
|
2008-09-26 22:27:26 -06:00
|
|
|
|
2010-06-14 12:24:51 -06:00
|
|
|
exportlist = list(exportlist, n);
|
2008-09-26 22:27:26 -06:00
|
|
|
}
|
|
|
|
|
2011-12-05 12:40:19 -07:00
|
|
|
// Mark n's symbol as package-local
|
2010-06-14 12:24:51 -06:00
|
|
|
static void
|
2009-08-04 23:59:23 -06:00
|
|
|
packagesym(Node *n)
|
2008-11-14 17:35:08 -07:00
|
|
|
{
|
2009-08-04 23:59:23 -06:00
|
|
|
if(n == N || n->sym == S)
|
2008-11-14 17:35:08 -07:00
|
|
|
return;
|
2009-08-04 23:59:23 -06:00
|
|
|
if(n->sym->flags & (SymExport|SymPackage)) {
|
|
|
|
if(n->sym->flags & SymExport)
|
|
|
|
yyerror("export/package mismatch: %S", n->sym);
|
2008-11-14 17:35:08 -07:00
|
|
|
return;
|
|
|
|
}
|
2009-08-04 23:59:23 -06:00
|
|
|
n->sym->flags |= SymPackage;
|
2008-11-14 17:35:08 -07:00
|
|
|
|
2010-06-14 12:24:51 -06:00
|
|
|
exportlist = list(exportlist, n);
|
2008-11-14 17:35:08 -07:00
|
|
|
}
|
2008-09-24 15:12:21 -06:00
|
|
|
|
2009-01-15 17:16:52 -07:00
|
|
|
int
|
|
|
|
exportname(char *s)
|
|
|
|
{
|
|
|
|
Rune r;
|
|
|
|
|
|
|
|
if((uchar)s[0] < Runeself)
|
|
|
|
return 'A' <= s[0] && s[0] <= 'Z';
|
|
|
|
chartorune(&r, s);
|
|
|
|
return isupperrune(r);
|
|
|
|
}
|
|
|
|
|
2011-03-02 14:18:17 -07:00
|
|
|
static int
|
|
|
|
initname(char *s)
|
|
|
|
{
|
|
|
|
return strcmp(s, "init") == 0;
|
|
|
|
}
|
|
|
|
|
2009-01-15 17:16:52 -07:00
|
|
|
void
|
2009-08-04 23:59:23 -06:00
|
|
|
autoexport(Node *n, int ctxt)
|
2009-01-15 17:16:52 -07:00
|
|
|
{
|
2009-08-04 23:59:23 -06:00
|
|
|
if(n == N || n->sym == S)
|
2009-01-15 17:16:52 -07:00
|
|
|
return;
|
2009-08-04 23:59:23 -06:00
|
|
|
if((ctxt != PEXTERN && ctxt != PFUNC) || dclcontext != PEXTERN)
|
2009-01-15 17:16:52 -07:00
|
|
|
return;
|
2009-08-07 13:50:26 -06:00
|
|
|
if(n->ntype && n->ntype->op == OTFUNC && n->ntype->left) // method
|
|
|
|
return;
|
2011-03-02 14:18:17 -07:00
|
|
|
if(exportname(n->sym->name) || initname(n->sym->name))
|
2009-08-04 23:59:23 -06:00
|
|
|
exportsym(n);
|
|
|
|
else
|
|
|
|
packagesym(n);
|
2009-01-15 17:16:52 -07:00
|
|
|
}
|
|
|
|
|
2010-06-14 12:24:51 -06:00
|
|
|
static void
|
2010-01-22 18:06:20 -07:00
|
|
|
dumppkg(Pkg *p)
|
|
|
|
{
|
2011-03-14 11:22:34 -06:00
|
|
|
char *suffix;
|
|
|
|
|
2011-12-14 07:05:33 -07:00
|
|
|
if(p == nil || p == localpkg || p->exported || p == builtinpkg)
|
2010-01-22 18:06:20 -07:00
|
|
|
return;
|
|
|
|
p->exported = 1;
|
2011-03-14 11:22:34 -06:00
|
|
|
suffix = "";
|
|
|
|
if(!p->direct)
|
|
|
|
suffix = " // indirect";
|
|
|
|
Bprint(bout, "\timport %s \"%Z\"%s\n", p->name, p->path, suffix);
|
2010-01-22 18:06:20 -07:00
|
|
|
}
|
|
|
|
|
2011-12-14 07:05:33 -07:00
|
|
|
// Look for anything we need for the inline body
|
|
|
|
static void reexportdep(Node *n);
|
|
|
|
static void
|
|
|
|
reexportdeplist(NodeList *ll)
|
|
|
|
{
|
|
|
|
for(; ll ;ll=ll->next)
|
|
|
|
reexportdep(ll->n);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
reexportdep(Node *n)
|
|
|
|
{
|
|
|
|
Type *t;
|
|
|
|
|
|
|
|
if(!n)
|
|
|
|
return;
|
|
|
|
|
2012-01-10 13:24:31 -07:00
|
|
|
// print("reexportdep %+hN\n", n);
|
2011-12-14 07:05:33 -07:00
|
|
|
switch(n->op) {
|
|
|
|
case ONAME:
|
|
|
|
switch(n->class&~PHEAP) {
|
|
|
|
case PFUNC:
|
2012-01-10 13:24:31 -07:00
|
|
|
// methods will be printed along with their type
|
|
|
|
if(!n->type || n->type->thistuple > 0)
|
|
|
|
break;
|
|
|
|
// fallthrough
|
2011-12-14 07:05:33 -07:00
|
|
|
case PEXTERN:
|
|
|
|
if (n->sym && n->sym->pkg != localpkg && n->sym->pkg != builtinpkg)
|
|
|
|
exportlist = list(exportlist, n);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2012-01-10 13:24:31 -07:00
|
|
|
|
2011-12-14 07:05:33 -07:00
|
|
|
case OLITERAL:
|
2012-01-10 13:24:31 -07:00
|
|
|
t = n->type;
|
2012-02-21 20:54:07 -07:00
|
|
|
if(t != types[n->type->etype] && t != idealbool && t != idealstring) {
|
2012-01-10 13:24:31 -07:00
|
|
|
if(isptr[t->etype])
|
|
|
|
t = t->type;
|
|
|
|
if (t && t->sym && t->sym->def && t->sym->pkg != localpkg && t->sym->pkg != builtinpkg) {
|
|
|
|
// print("reexport literal type %+hN\n", t->sym->def);
|
|
|
|
exportlist = list(exportlist, t->sym->def);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// fallthrough
|
|
|
|
case OTYPE:
|
2011-12-14 07:05:33 -07:00
|
|
|
if (n->sym && n->sym->pkg != localpkg && n->sym->pkg != builtinpkg)
|
|
|
|
exportlist = list(exportlist, n);
|
|
|
|
break;
|
|
|
|
|
|
|
|
// for operations that need a type when rendered, put the type on the export list.
|
|
|
|
case OCONV:
|
|
|
|
case OCONVIFACE:
|
|
|
|
case OCONVNOP:
|
|
|
|
case ODOTTYPE:
|
|
|
|
case OSTRUCTLIT:
|
|
|
|
case OPTRLIT:
|
|
|
|
t = n->type;
|
|
|
|
if(!t->sym && t->type)
|
|
|
|
t = t->type;
|
|
|
|
if (t && t->sym && t->sym->def && t->sym->pkg != localpkg && t->sym->pkg != builtinpkg) {
|
|
|
|
// print("reexport convnop %+hN\n", t->sym->def);
|
|
|
|
exportlist = list(exportlist, t->sym->def);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
reexportdep(n->left);
|
|
|
|
reexportdep(n->right);
|
|
|
|
reexportdeplist(n->list);
|
|
|
|
reexportdeplist(n->rlist);
|
|
|
|
reexportdeplist(n->ninit);
|
|
|
|
reexportdep(n->ntest);
|
|
|
|
reexportdep(n->nincr);
|
|
|
|
reexportdeplist(n->nbody);
|
|
|
|
reexportdeplist(n->nelse);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-06-14 12:24:51 -06:00
|
|
|
static void
|
2008-06-04 15:37:38 -06:00
|
|
|
dumpexportconst(Sym *s)
|
|
|
|
{
|
|
|
|
Node *n;
|
|
|
|
Type *t;
|
|
|
|
|
2009-06-06 13:46:38 -06:00
|
|
|
n = s->def;
|
2009-08-04 17:53:06 -06:00
|
|
|
typecheck(&n, Erv);
|
2008-06-04 15:37:38 -06:00
|
|
|
if(n == N || n->op != OLITERAL)
|
2008-07-27 14:09:15 -06:00
|
|
|
fatal("dumpexportconst: oconst nil: %S", s);
|
2008-06-04 15:37:38 -06:00
|
|
|
|
|
|
|
t = n->type; // may or may not be specified
|
2011-10-31 11:09:40 -06:00
|
|
|
dumpexporttype(t);
|
2008-06-04 15:37:38 -06:00
|
|
|
|
2009-09-21 16:45:55 -06:00
|
|
|
if(t != T && !isideal(t))
|
2011-10-31 11:09:40 -06:00
|
|
|
Bprint(bout, "\tconst %#S %#T = %#V\n", s, t, &n->val);
|
|
|
|
else
|
|
|
|
Bprint(bout, "\tconst %#S = %#V\n", s, &n->val);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
|
|
|
|
2010-06-14 12:24:51 -06:00
|
|
|
static void
|
2008-06-04 15:37:38 -06:00
|
|
|
dumpexportvar(Sym *s)
|
|
|
|
{
|
|
|
|
Node *n;
|
|
|
|
Type *t;
|
|
|
|
|
2009-06-06 13:46:38 -06:00
|
|
|
n = s->def;
|
2012-01-10 13:24:31 -07:00
|
|
|
typecheck(&n, Erv|Ecall);
|
2008-07-05 18:43:25 -06:00
|
|
|
if(n == N || n->type == T) {
|
2008-07-14 21:40:48 -06:00
|
|
|
yyerror("variable exported but not defined: %S", s);
|
2008-07-05 18:43:25 -06:00
|
|
|
return;
|
|
|
|
}
|
2008-06-04 15:37:38 -06:00
|
|
|
|
|
|
|
t = n->type;
|
2011-10-31 11:09:40 -06:00
|
|
|
dumpexporttype(t);
|
2008-06-04 15:37:38 -06:00
|
|
|
|
2011-12-14 07:05:33 -07:00
|
|
|
if(t->etype == TFUNC && n->class == PFUNC) {
|
|
|
|
if (n->inl) {
|
2012-01-10 13:24:31 -07:00
|
|
|
// when lazily typechecking inlined bodies, some re-exported ones may not have been typechecked yet.
|
|
|
|
// currently that can leave unresolved ONONAMEs in import-dot-ed packages in the wrong package
|
|
|
|
if(debug['l'] < 2)
|
|
|
|
typecheckinl(n);
|
2011-12-14 07:05:33 -07:00
|
|
|
Bprint(bout, "\tfunc %#S%#hT { %#H }\n", s, t, n->inl);
|
|
|
|
reexportdeplist(n->inl);
|
|
|
|
} else
|
|
|
|
Bprint(bout, "\tfunc %#S%#hT\n", s, t);
|
|
|
|
} else
|
2011-10-31 11:09:40 -06:00
|
|
|
Bprint(bout, "\tvar %#S %#T\n", s, t);
|
2008-10-03 17:15:55 -06:00
|
|
|
}
|
|
|
|
|
2010-06-08 19:50:02 -06:00
|
|
|
static int
|
|
|
|
methcmp(const void *va, const void *vb)
|
|
|
|
{
|
|
|
|
Type *a, *b;
|
|
|
|
|
|
|
|
a = *(Type**)va;
|
|
|
|
b = *(Type**)vb;
|
|
|
|
return strcmp(a->sym->name, b->sym->name);
|
|
|
|
}
|
|
|
|
|
2010-06-14 12:24:51 -06:00
|
|
|
static void
|
2011-10-31 11:09:40 -06:00
|
|
|
dumpexporttype(Type *t)
|
2008-10-03 17:15:55 -06:00
|
|
|
{
|
2011-10-31 11:09:40 -06:00
|
|
|
Type *f;
|
2010-06-08 19:50:02 -06:00
|
|
|
Type **m;
|
|
|
|
int i, n;
|
2008-06-04 15:37:38 -06:00
|
|
|
|
2011-10-31 11:09:40 -06:00
|
|
|
if(t == T)
|
|
|
|
return;
|
2011-11-01 19:46:41 -06:00
|
|
|
if(t->printed || t == types[t->etype] || t == bytetype || t == runetype || t == errortype)
|
2011-10-31 11:09:40 -06:00
|
|
|
return;
|
|
|
|
t->printed = 1;
|
|
|
|
|
|
|
|
if(t->sym != S && t->etype != TFIELD)
|
|
|
|
dumppkg(t->sym->pkg);
|
|
|
|
|
|
|
|
dumpexporttype(t->type);
|
|
|
|
dumpexporttype(t->down);
|
|
|
|
|
|
|
|
if (t->sym == S || t->etype == TFIELD)
|
|
|
|
return;
|
|
|
|
|
|
|
|
n = 0;
|
|
|
|
for(f=t->method; f!=T; f=f->down) {
|
|
|
|
dumpexporttype(f);
|
|
|
|
n++;
|
|
|
|
}
|
|
|
|
|
|
|
|
m = mal(n*sizeof m[0]);
|
|
|
|
i = 0;
|
|
|
|
for(f=t->method; f!=T; f=f->down)
|
|
|
|
m[i++] = f;
|
|
|
|
qsort(m, n, sizeof m[0], methcmp);
|
|
|
|
|
|
|
|
Bprint(bout, "\ttype %#S %#lT\n", t->sym, t);
|
|
|
|
for(i=0; i<n; i++) {
|
|
|
|
f = m[i];
|
2011-12-14 07:05:33 -07:00
|
|
|
if (f->type->nname && f->type->nname->inl) { // nname was set by caninl
|
2012-01-10 13:24:31 -07:00
|
|
|
// when lazily typechecking inlined bodies, some re-exported ones may not have been typechecked yet.
|
|
|
|
// currently that can leave unresolved ONONAMEs in import-dot-ed packages in the wrong package
|
|
|
|
if(debug['l'] < 2)
|
|
|
|
typecheckinl(f->type->nname);
|
2011-12-14 07:05:33 -07:00
|
|
|
Bprint(bout, "\tfunc (%#T) %#hhS%#hT { %#H }\n", getthisx(f->type)->type, f->sym, f->type, f->type->nname->inl);
|
|
|
|
reexportdeplist(f->type->nname->inl);
|
|
|
|
} else
|
|
|
|
Bprint(bout, "\tfunc (%#T) %#hhS%#hT\n", getthisx(f->type)->type, f->sym, f->type);
|
2011-10-31 11:09:40 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
dumpsym(Sym *s)
|
|
|
|
{
|
2009-08-04 23:59:23 -06:00
|
|
|
if(s->flags & SymExported)
|
2008-06-04 15:37:38 -06:00
|
|
|
return;
|
2009-08-04 23:59:23 -06:00
|
|
|
s->flags |= SymExported;
|
2008-06-04 15:37:38 -06:00
|
|
|
|
2009-06-06 13:46:38 -06:00
|
|
|
if(s->def == N) {
|
2008-09-30 14:49:31 -06:00
|
|
|
yyerror("unknown export symbol: %S", s);
|
2009-06-06 13:46:38 -06:00
|
|
|
return;
|
|
|
|
}
|
2012-01-10 13:24:31 -07:00
|
|
|
// print("dumpsym %O %+S\n", s->def->op, s);
|
2010-01-22 18:06:20 -07:00
|
|
|
dumppkg(s->pkg);
|
|
|
|
|
2009-06-06 13:46:38 -06:00
|
|
|
switch(s->def->op) {
|
|
|
|
default:
|
|
|
|
yyerror("unexpected export symbol: %O %S", s->def->op, s);
|
2008-06-04 15:37:38 -06:00
|
|
|
break;
|
2011-12-05 12:40:19 -07:00
|
|
|
|
2009-06-06 13:46:38 -06:00
|
|
|
case OLITERAL:
|
|
|
|
dumpexportconst(s);
|
2008-06-04 15:37:38 -06:00
|
|
|
break;
|
2011-12-05 12:40:19 -07:00
|
|
|
|
2009-06-06 13:46:38 -06:00
|
|
|
case OTYPE:
|
2011-10-31 11:09:40 -06:00
|
|
|
if(s->def->type->etype == TFORW)
|
|
|
|
yyerror("export of incomplete type %S", s);
|
|
|
|
else
|
|
|
|
dumpexporttype(s->def->type);
|
2008-06-04 15:37:38 -06:00
|
|
|
break;
|
2011-12-05 12:40:19 -07:00
|
|
|
|
2009-06-06 13:46:38 -06:00
|
|
|
case ONAME:
|
|
|
|
dumpexportvar(s);
|
2008-06-04 15:37:38 -06:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
dumpexport(void)
|
|
|
|
{
|
2009-08-04 23:59:23 -06:00
|
|
|
NodeList *l;
|
2011-03-14 11:22:34 -06:00
|
|
|
int32 i, lno;
|
|
|
|
Pkg *p;
|
2008-06-04 15:37:38 -06:00
|
|
|
|
2008-06-26 18:54:44 -06:00
|
|
|
lno = lineno;
|
2008-06-04 15:37:38 -06:00
|
|
|
|
2011-10-31 11:09:40 -06:00
|
|
|
Bprint(bout, "\n$$ // exports\n package %s", localpkg->name);
|
2010-06-11 16:28:43 -06:00
|
|
|
if(safemode)
|
|
|
|
Bprint(bout, " safe");
|
|
|
|
Bprint(bout, "\n");
|
2008-06-12 22:48:56 -06:00
|
|
|
|
2011-03-14 11:22:34 -06:00
|
|
|
for(i=0; i<nelem(phash); i++)
|
|
|
|
for(p=phash[i]; p; p=p->link)
|
|
|
|
if(p->direct)
|
|
|
|
dumppkg(p);
|
|
|
|
|
2009-08-04 23:59:23 -06:00
|
|
|
for(l=exportlist; l; l=l->next) {
|
|
|
|
lineno = l->n->lineno;
|
|
|
|
dumpsym(l->n->sym);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
|
|
|
|
2011-10-31 11:09:40 -06:00
|
|
|
Bprint(bout, "\n$$ // local types\n\n$$\n"); // 6l expects this. (see ld/go.c)
|
2008-06-04 15:37:38 -06:00
|
|
|
|
2008-06-26 18:54:44 -06:00
|
|
|
lineno = lno;
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2008-10-03 17:15:55 -06:00
|
|
|
* import
|
2008-06-04 15:37:38 -06:00
|
|
|
*/
|
2008-09-24 15:12:21 -06:00
|
|
|
|
2008-10-03 17:15:55 -06:00
|
|
|
/*
|
|
|
|
* return the sym for ss, which should match lexical
|
|
|
|
*/
|
2008-06-11 22:06:26 -06:00
|
|
|
Sym*
|
2009-06-06 13:46:38 -06:00
|
|
|
importsym(Sym *s, int op)
|
2008-06-11 22:06:26 -06:00
|
|
|
{
|
2009-08-19 16:18:08 -06:00
|
|
|
if(s->def != N && s->def->op != op)
|
|
|
|
redeclare(s, "during import");
|
2009-06-29 16:13:37 -06:00
|
|
|
|
|
|
|
// mark the symbol so it is not reexported
|
|
|
|
if(s->def == N) {
|
2011-03-02 14:18:17 -07:00
|
|
|
if(exportname(s->name) || initname(s->name))
|
2009-08-04 23:59:23 -06:00
|
|
|
s->flags |= SymExport;
|
2009-06-29 16:13:37 -06:00
|
|
|
else
|
2009-08-04 23:59:23 -06:00
|
|
|
s->flags |= SymPackage; // package scope
|
2009-06-29 16:13:37 -06:00
|
|
|
}
|
2008-06-11 22:06:26 -06:00
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
2008-06-04 15:37:38 -06:00
|
|
|
/*
|
2008-10-03 17:15:55 -06:00
|
|
|
* return the type pkg.name, forward declaring if needed
|
2008-06-04 15:37:38 -06:00
|
|
|
*/
|
2008-10-03 17:15:55 -06:00
|
|
|
Type*
|
2009-06-06 13:46:38 -06:00
|
|
|
pkgtype(Sym *s)
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2008-10-03 17:15:55 -06:00
|
|
|
Type *t;
|
2008-06-04 15:37:38 -06:00
|
|
|
|
2009-06-06 13:46:38 -06:00
|
|
|
importsym(s, OTYPE);
|
|
|
|
if(s->def == N || s->def->op != OTYPE) {
|
2008-10-03 17:15:55 -06:00
|
|
|
t = typ(TFORW);
|
|
|
|
t->sym = s;
|
2009-06-06 13:46:38 -06:00
|
|
|
s->def = typenod(t);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
2009-08-12 14:18:19 -06:00
|
|
|
if(s->def->type == T)
|
2011-10-31 11:09:40 -06:00
|
|
|
yyerror("pkgtype %S", s);
|
2009-06-06 13:46:38 -06:00
|
|
|
return s->def->type;
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
|
|
|
|
2011-12-05 12:40:19 -07:00
|
|
|
void
|
|
|
|
importimport(Sym *s, Strlit *z)
|
2008-11-14 17:35:08 -07:00
|
|
|
{
|
2011-12-05 12:40:19 -07:00
|
|
|
// Informational: record package name
|
|
|
|
// associated with import path, for use in
|
|
|
|
// human-readable messages.
|
|
|
|
Pkg *p;
|
|
|
|
|
|
|
|
p = mkpkg(z);
|
|
|
|
if(p->name == nil) {
|
|
|
|
p->name = s->name;
|
|
|
|
pkglookup(s->name, nil)->npkg++;
|
|
|
|
} else if(strcmp(p->name, s->name) != 0)
|
|
|
|
yyerror("conflicting names %s and %s for package \"%Z\"", p->name, s->name, p->path);
|
|
|
|
|
|
|
|
if(!incannedimport && myimportpath != nil && strcmp(z->s, myimportpath) == 0) {
|
|
|
|
yyerror("import \"%Z\": package depends on \"%Z\" (import cycle)", importpkg->path, z);
|
|
|
|
errorexit();
|
|
|
|
}
|
2008-11-14 17:35:08 -07:00
|
|
|
}
|
|
|
|
|
2008-06-04 15:37:38 -06:00
|
|
|
void
|
2009-06-06 13:46:38 -06:00
|
|
|
importconst(Sym *s, Type *t, Node *n)
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2009-08-12 14:18:19 -06:00
|
|
|
Node *n1;
|
|
|
|
|
2009-06-06 13:46:38 -06:00
|
|
|
importsym(s, OLITERAL);
|
2009-07-17 14:38:16 -06:00
|
|
|
convlit(&n, t);
|
2011-12-05 12:40:19 -07:00
|
|
|
|
|
|
|
if(s->def != N) // TODO: check if already the same.
|
2008-10-03 17:15:55 -06:00
|
|
|
return;
|
2008-06-04 15:37:38 -06:00
|
|
|
|
2009-08-04 23:59:23 -06:00
|
|
|
if(n->op != OLITERAL) {
|
|
|
|
yyerror("expression must be a constant");
|
|
|
|
return;
|
|
|
|
}
|
2011-12-05 12:40:19 -07:00
|
|
|
|
2009-08-12 14:18:19 -06:00
|
|
|
if(n->sym != S) {
|
|
|
|
n1 = nod(OXXX, N, N);
|
|
|
|
*n1 = *n;
|
|
|
|
n = n1;
|
|
|
|
}
|
2012-01-29 02:35:11 -07:00
|
|
|
n->orig = newname(s);
|
2009-08-04 23:59:23 -06:00
|
|
|
n->sym = s;
|
|
|
|
declare(n, PEXTERN);
|
2008-06-04 15:37:38 -06:00
|
|
|
|
2009-03-12 20:04:38 -06:00
|
|
|
if(debug['E'])
|
2008-10-03 17:15:55 -06:00
|
|
|
print("import const %S\n", s);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2011-12-05 12:40:19 -07:00
|
|
|
importvar(Sym *s, Type *t)
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2009-08-04 23:59:23 -06:00
|
|
|
Node *n;
|
|
|
|
|
2009-06-06 13:46:38 -06:00
|
|
|
importsym(s, ONAME);
|
|
|
|
if(s->def != N && s->def->op == ONAME) {
|
2010-06-08 19:50:02 -06:00
|
|
|
if(eqtype(t, s->def->type))
|
2008-10-03 17:15:55 -06:00
|
|
|
return;
|
2011-10-31 11:09:40 -06:00
|
|
|
yyerror("inconsistent definition for var %S during import\n\t%T\n\t%T", s, s->def->type, t);
|
2008-10-03 17:15:55 -06:00
|
|
|
}
|
2009-08-04 23:59:23 -06:00
|
|
|
n = newname(s);
|
|
|
|
n->type = t;
|
2011-12-05 12:40:19 -07:00
|
|
|
declare(n, PEXTERN);
|
2008-06-15 21:24:30 -06:00
|
|
|
|
2009-03-12 20:04:38 -06:00
|
|
|
if(debug['E'])
|
2008-10-03 17:15:55 -06:00
|
|
|
print("import var %S %lT\n", s, t);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2009-08-07 13:50:26 -06:00
|
|
|
importtype(Type *pt, Type *t)
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2011-11-29 05:34:08 -07:00
|
|
|
Node *n;
|
|
|
|
|
2011-12-05 12:40:19 -07:00
|
|
|
// override declaration in unsafe.go for Pointer.
|
|
|
|
// there is no way in Go code to define unsafe.Pointer
|
|
|
|
// so we have to supply it.
|
|
|
|
if(incannedimport &&
|
|
|
|
strcmp(importpkg->name, "unsafe") == 0 &&
|
|
|
|
strcmp(pt->nod->sym->name, "Pointer") == 0) {
|
|
|
|
t = types[TUNSAFEPTR];
|
2011-11-29 05:34:08 -07:00
|
|
|
}
|
2008-06-04 15:37:38 -06:00
|
|
|
|
2011-12-05 12:40:19 -07:00
|
|
|
if(pt->etype == TFORW) {
|
|
|
|
n = pt->nod;
|
|
|
|
copytype(pt->nod, t);
|
|
|
|
pt->nod = n; // unzero nod
|
|
|
|
pt->sym->lastlineno = parserline();
|
|
|
|
declare(n, PEXTERN);
|
|
|
|
checkwidth(pt);
|
2012-01-20 15:14:09 -07:00
|
|
|
} else if(!eqtype(pt->orig, t))
|
2012-01-17 02:00:57 -07:00
|
|
|
yyerror("inconsistent definition for type %S during import\n\t%lT\n\t%lT", pt->sym, pt, t);
|
2011-12-05 12:40:19 -07:00
|
|
|
|
2009-03-12 20:04:38 -06:00
|
|
|
if(debug['E'])
|
2009-08-07 13:50:26 -06:00
|
|
|
print("import type %T %lT\n", pt, t);
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|