summaryrefslogtreecommitdiff
path: root/src/cmd/gc/export.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/gc/export.c')
-rw-r--r--src/cmd/gc/export.c96
1 files changed, 64 insertions, 32 deletions
diff --git a/src/cmd/gc/export.c b/src/cmd/gc/export.c
index bbed8ae36..b7311665a 100644
--- a/src/cmd/gc/export.c
+++ b/src/cmd/gc/export.c
@@ -22,22 +22,8 @@ exportsym(Node *n)
}
n->sym->flags |= SymExport;
- exportlist = list(exportlist, n);
-}
-
-// Mark n's symbol as package-local
-static void
-packagesym(Node *n)
-{
- if(n == N || n->sym == S)
- return;
- if(n->sym->flags & (SymExport|SymPackage)) {
- if(n->sym->flags & SymExport)
- yyerror("export/package mismatch: %S", n->sym);
- return;
- }
- n->sym->flags |= SymPackage;
-
+ if(debug['E'])
+ print("export symbol %S\n", n->sym);
exportlist = list(exportlist, n);
}
@@ -58,6 +44,18 @@ initname(char *s)
return strcmp(s, "init") == 0;
}
+// exportedsym returns whether a symbol will be visible
+// to files that import our package.
+static int
+exportedsym(Sym *sym)
+{
+ // Builtins are visible everywhere.
+ if(sym->pkg == builtinpkg || sym->origpkg == builtinpkg)
+ return 1;
+
+ return sym->pkg == localpkg && exportname(sym->name);
+}
+
void
autoexport(Node *n, int ctxt)
{
@@ -67,10 +65,9 @@ autoexport(Node *n, int ctxt)
return;
if(n->ntype && n->ntype->op == OTFUNC && n->ntype->left) // method
return;
- if(exportname(n->sym->name) || initname(n->sym->name))
+ // -A is for cmd/gc/mkbuiltin script, so export everything
+ if(debug['A'] || exportname(n->sym->name) || initname(n->sym->name))
exportsym(n);
- else
- packagesym(n);
}
static void
@@ -104,36 +101,60 @@ reexportdep(Node *n)
if(!n)
return;
-// print("reexportdep %+hN\n", n);
+ //print("reexportdep %+hN\n", n);
switch(n->op) {
case ONAME:
switch(n->class&~PHEAP) {
case PFUNC:
// methods will be printed along with their type
+ // nodes for T.Method expressions
+ if(n->left && n->left->op == OTYPE)
+ break;
+ // nodes for method calls.
if(!n->type || n->type->thistuple > 0)
break;
// fallthrough
case PEXTERN:
- if (n->sym && n->sym->pkg != localpkg && n->sym->pkg != builtinpkg)
+ if(n->sym && !exportedsym(n->sym)) {
+ if(debug['E'])
+ print("reexport name %S\n", n->sym);
exportlist = list(exportlist, n);
+ }
}
break;
+ case ODCL:
+ // Local variables in the bodies need their type.
+ t = n->left->type;
+ if(t != types[t->etype] && t != idealbool && t != idealstring) {
+ if(isptr[t->etype])
+ t = t->type;
+ if(t && t->sym && t->sym->def && !exportedsym(t->sym)) {
+ if(debug['E'])
+ print("reexport type %S from declaration\n", t->sym);
+ exportlist = list(exportlist, t->sym->def);
+ }
+ }
+ break;
case OLITERAL:
t = n->type;
if(t != types[n->type->etype] && t != idealbool && t != idealstring) {
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);
+ if(t && t->sym && t->sym->def && !exportedsym(t->sym)) {
+ if(debug['E'])
+ print("reexport literal type %S\n", t->sym);
exportlist = list(exportlist, t->sym->def);
}
}
// fallthrough
case OTYPE:
- if (n->sym && n->sym->pkg != localpkg && n->sym->pkg != builtinpkg)
+ if(n->sym && !exportedsym(n->sym)) {
+ if(debug['E'])
+ print("reexport literal/type %S\n", n->sym);
exportlist = list(exportlist, n);
+ }
break;
// for operations that need a type when rendered, put the type on the export list.
@@ -141,13 +162,15 @@ reexportdep(Node *n)
case OCONVIFACE:
case OCONVNOP:
case ODOTTYPE:
+ case ODOTTYPE2:
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);
+ if(t && t->sym && t->sym->def && !exportedsym(t->sym)) {
+ if(debug['E'])
+ print("reexport type for convnop %S\n", t->sym);
exportlist = list(exportlist, t->sym->def);
}
break;
@@ -207,10 +230,11 @@ dumpexportvar(Sym *s)
// currently that can leave unresolved ONONAMEs in import-dot-ed packages in the wrong package
if(debug['l'] < 2)
typecheckinl(n);
- Bprint(bout, "\tfunc %#S%#hT { %#H }\n", s, t, n->inl);
+ // NOTE: The space after %#S here is necessary for ld's export data parser.
+ Bprint(bout, "\tfunc %#S %#hT { %#H }\n", s, t, n->inl);
reexportdeplist(n->inl);
} else
- Bprint(bout, "\tfunc %#S%#hT\n", s, t);
+ Bprint(bout, "\tfunc %#S %#hT\n", s, t);
} else
Bprint(bout, "\tvar %#S %#T\n", s, t);
}
@@ -262,15 +286,17 @@ dumpexporttype(Type *t)
Bprint(bout, "\ttype %#S %#lT\n", t->sym, t);
for(i=0; i<n; i++) {
f = m[i];
+ if(f->nointerface)
+ Bprint(bout, "\t//go:nointerface\n");
if (f->type->nname && f->type->nname->inl) { // nname was set by caninl
// 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);
- Bprint(bout, "\tfunc (%#T) %#hhS%#hT { %#H }\n", getthisx(f->type)->type, f->sym, f->type, f->type->nname->inl);
+ 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);
+ Bprint(bout, "\tfunc (%#T) %#hhS %#hT\n", getthisx(f->type)->type, f->sym, f->type);
}
}
@@ -349,8 +375,12 @@ dumpexport(void)
Sym*
importsym(Sym *s, int op)
{
- if(s->def != N && s->def->op != op)
- redeclare(s, "during import");
+ char *pkgstr;
+
+ if(s->def != N && s->def->op != op) {
+ pkgstr = smprint("during import \"%Z\"", importpkg->path);
+ redeclare(s, pkgstr);
+ }
// mark the symbol so it is not reexported
if(s->def == N) {
@@ -389,6 +419,8 @@ importimport(Sym *s, Strlit *z)
// human-readable messages.
Pkg *p;
+ if(isbadimport(z))
+ errorexit();
p = mkpkg(z);
if(p->name == nil) {
p->name = s->name;