Commit 2a0e15d3 authored by Russ Cox's avatar Russ Cox

gc: add error type

R=ken
CC=golang-dev
https://golang.org/cl/5331043
parent b4e35629
...@@ -89,7 +89,6 @@ dumppkg(Pkg *p) ...@@ -89,7 +89,6 @@ dumppkg(Pkg *p)
} }
static void static void
dumpexportconst(Sym *s) dumpexportconst(Sym *s)
{ {
Node *n; Node *n;
...@@ -151,7 +150,7 @@ dumpexporttype(Type *t) ...@@ -151,7 +150,7 @@ dumpexporttype(Type *t)
if(t == T) if(t == T)
return; return;
if(t->printed || t == types[t->etype] || t == bytetype || t == runetype) if(t->printed || t == types[t->etype] || t == bytetype || t == runetype || t == errortype)
return; return;
t->printed = 1; t->printed = 1;
......
...@@ -553,6 +553,9 @@ typefmt(Fmt *fp, Type *t) ...@@ -553,6 +553,9 @@ typefmt(Fmt *fp, Type *t)
t = types[t->etype]; t = types[t->etype];
} }
if(t == errortype)
return fmtstrcpy(fp, "error");
// Unless the 'l' flag was specified, if the type has a name, just print that name. // Unless the 'l' flag was specified, if the type has a name, just print that name.
if(!(fp->flags&FmtLong) && t->sym && t->etype != TFIELD && t != types[t->etype]) { if(!(fp->flags&FmtLong) && t->sym && t->etype != TFIELD && t != types[t->etype]) {
switch(fmtmode) { switch(fmtmode) {
......
...@@ -786,6 +786,7 @@ EXTERN Type* idealstring; ...@@ -786,6 +786,7 @@ EXTERN Type* idealstring;
EXTERN Type* idealbool; EXTERN Type* idealbool;
EXTERN Type* bytetype; EXTERN Type* bytetype;
EXTERN Type* runetype; EXTERN Type* runetype;
EXTERN Type* errortype;
EXTERN uchar simtype[NTYPE]; EXTERN uchar simtype[NTYPE];
EXTERN uchar isptr[NTYPE]; EXTERN uchar isptr[NTYPE];
EXTERN uchar isforw[NTYPE]; EXTERN uchar isforw[NTYPE];
......
...@@ -1759,6 +1759,40 @@ static void ...@@ -1759,6 +1759,40 @@ static void
lexinit1(void) lexinit1(void)
{ {
Sym *s, *s1; Sym *s, *s1;
Type *t, *f, *rcvr, *in, *out;
// t = interface { Error() string }
rcvr = typ(TSTRUCT);
rcvr->type = typ(TFIELD);
rcvr->type->type = ptrto(typ(TSTRUCT));
rcvr->funarg = 1;
in = typ(TSTRUCT);
in->funarg = 1;
out = typ(TSTRUCT);
out->type = typ(TFIELD);
out->type->type = types[TSTRING];
out->funarg = 1;
f = typ(TFUNC);
*getthis(f) = rcvr;
*getoutarg(f) = out;
*getinarg(f) = in;
f->thistuple = 1;
f->intuple = 0;
f->outnamed = 0;
f->outtuple = 1;
t = typ(TINTER);
t->type = typ(TFIELD);
t->type->sym = lookup("Error");
t->type->type = f;
// error type
s = lookup("error");
s->lexical = LNAME;
errortype = t;
errortype->sym = s;
s1 = pkglookup("error", builtinpkg);
s1->lexical = LNAME;
s1->def = typenod(errortype);
// byte alias // byte alias
s = lookup("byte"); s = lookup("byte");
...@@ -1820,6 +1854,10 @@ lexfini(void) ...@@ -1820,6 +1854,10 @@ lexfini(void)
s = lookup("byte"); s = lookup("byte");
if(s->def == N) if(s->def == N)
s->def = typenod(bytetype); s->def = typenod(bytetype);
s = lookup("error");
if(s->def == N)
s->def = typenod(errortype);
s = lookup("rune"); s = lookup("rune");
if(s->def == N) if(s->def == N)
......
...@@ -693,8 +693,13 @@ dtypesym(Type *t) ...@@ -693,8 +693,13 @@ dtypesym(Type *t)
tbase = t->type; tbase = t->type;
dupok = tbase->sym == S; dupok = tbase->sym == S;
if(compiling_runtime && (tbase == types[tbase->etype] || tbase == bytetype || tbase == runetype)) // int, float, etc if(compiling_runtime &&
(tbase == types[tbase->etype] ||
tbase == bytetype ||
tbase == runetype ||
tbase == errortype)) { // int, float, etc
goto ok; goto ok;
}
// named types from other files are defined only by those files // named types from other files are defined only by those files
if(tbase->sym && !tbase->local) if(tbase->sym && !tbase->local)
...@@ -903,6 +908,13 @@ dumptypestructs(void) ...@@ -903,6 +908,13 @@ dumptypestructs(void)
dtypesym(ptrto(types[i])); dtypesym(ptrto(types[i]));
dtypesym(ptrto(types[TSTRING])); dtypesym(ptrto(types[TSTRING]));
dtypesym(ptrto(types[TUNSAFEPTR])); dtypesym(ptrto(types[TUNSAFEPTR]));
// emit type structs for error and func(error) string.
// The latter is the type of an auto-generated wrapper.
dtypesym(ptrto(errortype));
dtypesym(functype(nil,
list1(nod(ODCLFIELD, N, typenod(errortype))),
list1(nod(ODCLFIELD, N, typenod(types[TSTRING])))));
// add paths for runtime and main, which 6l imports implicitly. // add paths for runtime and main, which 6l imports implicitly.
dimportpath(runtimepkg); dimportpath(runtimepkg);
......
...@@ -1483,7 +1483,7 @@ ptrto(Type *t) ...@@ -1483,7 +1483,7 @@ ptrto(Type *t)
Type *t1; Type *t1;
if(tptr == 0) if(tptr == 0)
fatal("ptrto: nil"); fatal("ptrto: no tptr");
t1 = typ(tptr); t1 = typ(tptr);
t1->type = t; t1->type = t;
t1->width = widthptr; t1->width = widthptr;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment