}
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);
}
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)
{
return;
if(exportname(n->sym->name) || initname(n->sym->name))
exportsym(n);
- else
- packagesym(n);
}
static void
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
- if(!n->type || n->type->thistuple > 0)
+ if(n->left && n->left->op == OTYPE)
break;
// fallthrough
case PEXTERN:
- if (n->sym && n->sym->pkg != localpkg && n->sym->pkg != builtinpkg)
+ if(n->sym && !exportedsym(n->sym))
exportlist = list(exportlist, n);
}
break;
if(t != types[t->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) {
+ if(t && t->sym && t->sym->def && !exportedsym(t->sym)) {
exportlist = list(exportlist, t->sym->def);
}
}
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.
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;
s->lexical = lex;
etype = syms[i].etype;
- if(etype != Txxx && (etype != TANY || debug['A']) && s->def == N)
+ if(etype != Txxx && (etype != TANY || debug['A']) && s->def == N) {
s->def = typenod(types[etype]);
+ s->origpkg = builtinpkg;
+ }
etype = syms[i].op;
if(etype != OXXX && s->def == N) {
s->def->sym = s;
s->def->etype = etype;
s->def->builtin = 1;
+ s->origpkg = builtinpkg;
}
}
+ // backend-specific builtin types (e.g. int).
for(i=0; typedefs[i].name; i++) {
s = lookup(typedefs[i].name);
- if(s->def == N)
+ if(s->def == N) {
s->def = typenod(types[typedefs[i].etype]);
+ s->origpkg = builtinpkg;
+ }
}
// there's only so much table-driven we can handle.
// these are special cases.
s = lookup("byte");
- if(s->def == N)
+ if(s->def == N) {
s->def = typenod(bytetype);
-
+ s->origpkg = builtinpkg;
+ }
+
s = lookup("error");
- if(s->def == N)
+ if(s->def == N) {
s->def = typenod(errortype);
+ s->origpkg = builtinpkg;
+ }
s = lookup("rune");
- if(s->def == N)
+ if(s->def == N) {
s->def = typenod(runetype);
+ s->origpkg = builtinpkg;
+ }
s = lookup("nil");
if(s->def == N) {
v.ctype = CTNIL;
s->def = nodlit(v);
s->def->sym = s;
+ s->origpkg = builtinpkg;
}
-
+
s = lookup("iota");
if(s->def == N) {
s->def = nod(OIOTA, N, N);
s->def->sym = s;
+ s->origpkg = builtinpkg;
}
s = lookup("true");
if(s->def == N) {
s->def = nodbool(1);
s->def->sym = s;
+ s->origpkg = builtinpkg;
}
s = lookup("false");
if(s->def == N) {
s->def = nodbool(0);
s->def->sym = s;
+ s->origpkg = builtinpkg;
}
-
+
nodfp = nod(ONAME, N, N);
nodfp->type = types[TINT32];
nodfp->xoffset = 0;
--- /dev/null
+// Copyright 2012 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.
+
+// A package that redeclares common builtin names.
+package a
+
+var true = 0 == 1
+var false = 0 == 0
+var nil = 1
+
+const append = 42
+
+type error bool
+type int interface{}
+
+func len(interface{}) int32 { return 42 }
+
+func Test() {
+ var array [append]int
+ if true {
+ panic("unexpected builtin true instead of redeclared one")
+ }
+ if !false {
+ panic("unexpected builtin false instead of redeclared one")
+ }
+ if len(array) != 42 {
+ println(len(array))
+ panic("unexpected call of builtin len")
+ }
+}
+
+func InlinedFakeTrue() error { return error(true) }
+func InlinedFakeFalse() error { return error(false) }
+func InlinedFakeNil() int { return nil }