return;
foundstart:
- pkg = nil;
+ /* found $$; skip rest of line */
+ while((c = Bgetc(b)) != '\n')
+ if(c == Beof)
+ goto bad;
+
/* how big is it? */
+ pkg = nil;
first = 1;
start = end = 0;
for (n=0; n<size; n+=Blinelen(b)) {
{
int h;
Import *x;
-
+
h = hashstr(name) % NIHASH;
for(x=ihash[h]; x; x=x->hash)
if(x->name[0] == name[0] && strcmp(x->name, name) == 0)
char *p, *ep, *prefix, *name, *def;
Import *x;
- file = arstrdup(file);
+ file = arstrdup(file);
p = data;
ep = data + len;
while(parsepkgdata(&p, ep, &export, &prefix, &name, &def) > 0) {
fprint(2, "%s:\t%s %s %s\n", file, prefix, name, def);
errors++;
}
-
+
// okay if some .6 say export and others don't.
// all it takes is one.
if(export)
{
char *p, *prefix, *name, *def, *edef, *meth;
int n;
-
+
// skip white space
p = *pp;
while(p < ep && (*p == ' ' || *p == '\t'))
p += 7;
}
- // prefix: (var|type|func|const)
+ // prefix: (var|type|func|const)
prefix = p;
-
+
prefix = p;
if(p + 6 > ep)
return -1;
return -1;
}
p[-1] = '\0';
-
+
// name: a.b followed by space
name = p;
while(p < ep && *p != ' ')
return -1;
edef = p;
*p++ = '\0';
-
+
// include methods on successive lines in def of named type
while(parsemethod(&p, ep, &meth) > 0) {
*edef++ = '\n'; // overwrites '\0'
parsemethod(char **pp, char *ep, char **methp)
{
char *p;
-
+
// skip white space
p = *pp;
while(p < ep && (*p == ' ' || *p == '\t'))
// if it says "func (", it's a method
if(p + 6 >= ep || strncmp(p, "func (", 6) != 0)
return 0;
-
+
// definition to end of line
*methp = p;
while(p < ep && *p != '\n')
{
Import *a, *b;
int i;
-
+
a = *(Import**)va;
b = *(Import**)vb;
-
+
i = strcmp(a->prefix, b->prefix);
if(i != 0) {
// rewrite so "type" comes first
strappend(char *s, char *t)
{
int n;
-
+
n = strlen(t);
memmove(s, t, n);
return s+n;
// print them into buffer
data = armalloc(len);
-
+
// import\n
// $$\n
// pkgstmt\n
{
Dcl *r, *d;
Sym *s;
+ char *p;
+ static int typgen;
if(n==T || n->sym == S)
fatal("addtyp: n=%T t=%T nil", n);
else {
r = autodcl;
pushdcl(s);
+ p = smprint("%s_%d", s->name, ++typgen);
+ n->xsym = lookup(p);
+ free(p);
}
if(s->tblock == block)
d->dtype = n;
d->op = OTYPE;
+ d->back = r->back;
+ r->back->forw = d;
+ r->back = d;
+
+ d = dcl();
+ d->dtype = n;
+ d->op = OTYPE;
+
+ r = typelist;
+ d->back = r->back;
r->back->forw = d;
r->back = d;
d->dsym = s;
d->dnode = e;
d->op = OCONST;
-
+ d->back = r->back;
r->back->forw = d;
r->back = d;
if(t == T)
return;
- if(t->printed)
+ if(t->printed || t == types[t->etype] || t == types[TSTRING])
return;
t->printed = 1;
yyerror("export of incomplete type %T", s->otype);
return;
}
- Bprint(bout, "type %lS %l#T\n", s, s->otype);
+ Bprint(bout, "type %#T %l#T\n", s->otype, s->otype);
}
void
dumpexporttype(s);
for(f=s->otype->method; f!=T; f=f->down)
- Bprint(bout, "\tfunc (%#T) %hS %#T\n",
+ Bprint(bout, "\tfunc (%#T) %hS %#hT\n",
f->type->type->type, f->sym, f->type);
break;
case LNAME:
}
}
+void
+dumptype(Type *t)
+{
+ // no need to re-dump type if already exported
+ if(t->printed)
+ return;
+
+ // no need to dump type if it's not ours (was imported)
+ if(t->sym != S && t->sym->otype == t && !t->sym->local)
+ return;
+
+ Bprint(bout, "type %#T %l#T\n", t, t);
+}
+
void
dumpexport(void)
{
Dcl *d;
int32 lno;
- char *pkg;
- exporting = 1;
lno = lineno;
Bprint(bout, " import\n");
- Bprint(bout, " $$\n");
+ Bprint(bout, " $$ // exports\n");
Bprint(bout, " package %s\n", package);
- pkg = package;
- package = "$nopkg";
for(d=exportlist->forw; d!=D; d=d->forw) {
lineno = d->lineno;
dumpsym(d->dsym);
}
- package = pkg;
+ Bprint(bout, "\n$$ // local types\n");
+
+ for(d=typelist->forw; d!=D; d=d->forw) {
+ lineno = d->lineno;
+ dumptype(d->dtype);
+ }
Bprint(bout, "\n$$\n");
lineno = lno;
- exporting = 0;
}
/*
fatal("importsym: oops1 %N", ss);
s = pkgsym(ss->sym->name, ss->psym->name, lexical);
-
/* TODO botch - need some diagnostic checking for the following assignment */
s->opackage = ss->osym->name;
+ s->export = 1;
return s;
}
Type* method;
Sym* sym;
+ Sym* xsym; // export sym
int32 vargen; // unique name for OTYPE/ONAME
Node* nname;
EXTERN Dcl* externdcl;
EXTERN Dcl* exportlist;
EXTERN Dcl* signatlist;
+EXTERN Dcl* typelist;
EXTERN int dclcontext; // PEXTERN/PAUTO
EXTERN int importflag;
EXTERN int inimportsys;
exportlist = mal(sizeof(*exportlist));
exportlist->back = exportlist;
+ typelist = mal(sizeof(*typelist));
+ typelist->back = typelist;
+
// function field skeleton
fskel = nod(OLIST, N, nod(OLIST, N, N));
fskel->left = nod(ODCLFIELD, N, N);
continue;
}
t = typ(etype);
- switch(etype) {
- case TSTRING:
- case TCHAN:
- case TMAP:
+ if(etype == TSTRING)
t = ptrto(t);
- }
-
t->sym = s;
dowidth(t);
Tpretty(Fmt *fp, Type *t)
{
Type *t1;
+ Sym *s;
if(t->etype != TFIELD
&& t->sym != S
&& t->sym->name[0] != '_'
- && !(fp->flags&FmtLong))
- return fmtprint(fp, "%S", t->sym);
+ && !(fp->flags&FmtLong)) {
+ s = t->sym;
+ if(t == types[t->etype] || t == types[TSTRING])
+ return fmtprint(fp, "%s", s->name);
+ if(exporting) {
+ if(t->xsym != S)
+ s = t->xsym;
+ if(strcmp(s->opackage, package) == 0)
+ if(s->otype != t || !s->export)
+ return fmtprint(fp, "%lS_%s", s, filename);
+ return fmtprint(fp, "%lS", s);
+ }
+ return fmtprint(fp, "%S", s);
+ }
if(t->etype < nelem(basicnames) && basicnames[t->etype] != nil)
return fmtprint(fp, "%s", basicnames[t->etype]);
return -1;
}
+
+
int
Tconv(Fmt *fp)
{
char buf[500], buf1[500];
Type *t, *t1;
- int et;
+ int et, exp;
t = va_arg(fp->args, Type*);
if(t == T)
goto out;
}
- if(!debug['t'] && Tpretty(fp, t) >= 0) {
- t->trecur--;
- return 0;
+ if(!debug['t']) {
+ exp = (fp->flags & FmtSharp);
+ if(exp)
+ exporting++;
+ if(Tpretty(fp, t) >= 0) {
+ t->trecur--;
+ if(exp)
+ exporting--;
+ return 0;
+ }
+ if(exp)
+ exporting--;
}
et = t->etype;
BUG: fails incorrectly
=========== bugs/bug083.go
-BUG: succeeds incorrectly
+bugs/bug083.dir/bug1.go:5: syntax error near T0
=========== bugs/bug085.go
bugs/bug085.go:8: P: undefined
fixedbugs/bug016.go:7: overflow converting constant to uint32
=========== fixedbugs/bug025.go
-fixedbugs/bug025.go:7: variable exported but not defined: main.Foo
+fixedbugs/bug025.go:7: variable exported but not defined: Foo
=========== fixedbugs/bug027.go
hi