mirror of
https://github.com/golang/go
synced 2024-11-22 04:24:39 -07:00
change type names to go live at the name, so that
type T struct { next *T } and type T *struct { next T } are valid without needing forward declarations. add "type T struct" syntax for forward struct declarations. add "type T interface" syntax, but commented out (need to fix semicolons first) R=ken DELTA=452 (259 added, 115 deleted, 78 changed) OCL=16580 CL=16584
This commit is contained in:
parent
717de79976
commit
74e2e087e2
@ -105,6 +105,14 @@ dowidth(Type *t)
|
||||
if(t == T)
|
||||
return;
|
||||
|
||||
if(t->width == -2) {
|
||||
yyerror("invalid recursive type %T", t);
|
||||
t->width = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
t->width = -2;
|
||||
|
||||
w = 0;
|
||||
switch(t->etype) {
|
||||
default:
|
||||
@ -136,6 +144,7 @@ dowidth(Type *t)
|
||||
w = 10;
|
||||
break;
|
||||
case TINTER: // implemented as 2 pointers
|
||||
case TFORWINTER:
|
||||
offmod(t);
|
||||
w = 2*wptr;
|
||||
break;
|
||||
@ -148,7 +157,9 @@ dowidth(Type *t)
|
||||
dowidth(t->type);
|
||||
w = wptr;
|
||||
break;
|
||||
case TFORW: // implemented as pointer
|
||||
case TFORW: // should have been filled in
|
||||
case TFORWSTRUCT:
|
||||
yyerror("incomplete type %T", t);
|
||||
w = wptr;
|
||||
break;
|
||||
case TANY: // implemented as pointer
|
||||
|
@ -453,7 +453,7 @@ agen(Node *n, Node *res)
|
||||
case OIND:
|
||||
cgen(nl, res);
|
||||
break;
|
||||
|
||||
|
||||
case ODOT:
|
||||
t = nl->type;
|
||||
agen(nl, res);
|
||||
@ -632,7 +632,7 @@ bgen(Node *n, int true, Prog *to)
|
||||
tempname(&tmp, nr->type);
|
||||
gmove(&n1, &tmp);
|
||||
regfree(&n1);
|
||||
|
||||
|
||||
regalloc(&n1, nl->type, N);
|
||||
cgen(nl, &n1);
|
||||
|
||||
@ -711,6 +711,9 @@ sgen(Node *n, Node *ns, int32 w)
|
||||
fatal("sgen UINF");
|
||||
}
|
||||
|
||||
if(w < 0)
|
||||
fatal("sgen copy %d", w);
|
||||
|
||||
// offset on the stack
|
||||
osrc = stkof(n);
|
||||
odst = stkof(ns);
|
||||
|
@ -672,7 +672,7 @@ cgen_proc(Node *n)
|
||||
cgen_call(n->left, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
@ -802,7 +802,10 @@ cgen_as(Node *nl, Node *nr, int op)
|
||||
if(debug['g'])
|
||||
dump("\nclearfat", nl);
|
||||
|
||||
if(nl->type->width < 0)
|
||||
fatal("clearfat %T %lld", nl->type, nl->type->width);
|
||||
w = nl->type->width;
|
||||
|
||||
if(w > 0)
|
||||
gconreg(AMOVQ, 0, D_AX);
|
||||
|
||||
|
338
src/cmd/gc/dcl.c
338
src/cmd/gc/dcl.c
@ -20,38 +20,14 @@ dflag(void)
|
||||
void
|
||||
dodclvar(Node *n, Type *t)
|
||||
{
|
||||
|
||||
loop:
|
||||
if(n == N)
|
||||
return;
|
||||
|
||||
if(n->op == OLIST) {
|
||||
for(; n->op == OLIST; n = n->right)
|
||||
dodclvar(n->left, t);
|
||||
n = n->right;
|
||||
goto loop;
|
||||
}
|
||||
|
||||
if(exportadj)
|
||||
exportsym(n->sym);
|
||||
dowidth(t);
|
||||
addvar(n, t, dclcontext);
|
||||
}
|
||||
|
||||
void
|
||||
dodcltype(Type *n, Type *t)
|
||||
{
|
||||
Type *nt;
|
||||
|
||||
if(n == T)
|
||||
return;
|
||||
if(t->sym != S) {
|
||||
// botch -- should be a complete deep copy
|
||||
nt = typ(Txxx);
|
||||
*nt = *t;
|
||||
t = nt;
|
||||
t->sym = S;
|
||||
}
|
||||
n->sym->local = 1;
|
||||
addtyp(n, t, dclcontext);
|
||||
if(exportadj)
|
||||
exportsym(n->sym);
|
||||
}
|
||||
@ -59,49 +35,93 @@ dodcltype(Type *n, Type *t)
|
||||
void
|
||||
dodclconst(Node *n, Node *e)
|
||||
{
|
||||
Sym *s;
|
||||
Dcl *r, *d;
|
||||
|
||||
loop:
|
||||
if(n == N)
|
||||
return;
|
||||
if(n->op == OLIST) {
|
||||
dodclconst(n->left, e);
|
||||
n = n->right;
|
||||
goto loop;
|
||||
}
|
||||
|
||||
if(n->op != ONAME)
|
||||
fatal("dodclconst: not a name");
|
||||
|
||||
if(e->op != OLITERAL) {
|
||||
yyerror("expression must be a constant");
|
||||
return;
|
||||
}
|
||||
s = n->sym;
|
||||
|
||||
s->oconst = e;
|
||||
s->lexical = LACONST;
|
||||
for(; n->op == OLIST; n=n->right)
|
||||
dodclconst(n, e);
|
||||
|
||||
addconst(n, e, dclcontext);
|
||||
if(exportadj)
|
||||
exportsym(n->sym);
|
||||
|
||||
r = autodcl;
|
||||
if(dclcontext == PEXTERN)
|
||||
r = externdcl;
|
||||
|
||||
d = dcl();
|
||||
d->dsym = s;
|
||||
d->dnode = e;
|
||||
d->op = OCONST;
|
||||
|
||||
r->back->forw = d;
|
||||
r->back = d;
|
||||
|
||||
if(dflag())
|
||||
print("const-dcl %S %N\n", n->sym, n->sym->oconst);
|
||||
}
|
||||
|
||||
/*
|
||||
* introduce a type named n
|
||||
* but it is an unknown type for now
|
||||
*/
|
||||
Type*
|
||||
dodcltype(Type *n)
|
||||
{
|
||||
Sym *s;
|
||||
|
||||
// if n has been forward declared,
|
||||
// use the Type* created then
|
||||
s = n->sym;
|
||||
if(s->tblock == block) {
|
||||
switch(s->otype->etype) {
|
||||
case TFORWSTRUCT:
|
||||
case TFORWINTER:
|
||||
return s->otype;
|
||||
}
|
||||
}
|
||||
|
||||
// otherwise declare a new type
|
||||
addtyp(n, dclcontext);
|
||||
n->sym->local = 1;
|
||||
if(exportadj)
|
||||
exportsym(n->sym);
|
||||
return n;
|
||||
}
|
||||
|
||||
/*
|
||||
* now we know what n is: it's t
|
||||
*/
|
||||
void
|
||||
updatetype(Type *n, Type *t)
|
||||
{
|
||||
Sym *s;
|
||||
|
||||
s = n->sym;
|
||||
if(s == S || s->otype != n)
|
||||
fatal("updatetype %T = %T", n, t);
|
||||
|
||||
switch(n->etype) {
|
||||
case TFORW:
|
||||
break;
|
||||
|
||||
case TFORWSTRUCT:
|
||||
if(t->etype != TSTRUCT) {
|
||||
yyerror("%T forward declared as struct", n);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case TFORWINTER:
|
||||
if(t->etype != TINTER) {
|
||||
yyerror("%T forward declared as interface", n);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
fatal("updatetype %T / %T", n, t);
|
||||
}
|
||||
|
||||
*n = *t;
|
||||
n->sym = s;
|
||||
|
||||
// catch declaration of incomplete type
|
||||
switch(n->etype) {
|
||||
case TFORWSTRUCT:
|
||||
case TFORWINTER:
|
||||
break;
|
||||
default:
|
||||
checkwidth(n);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* return nelem of list
|
||||
*/
|
||||
@ -139,7 +159,7 @@ functype(Node *this, Node *in, Node *out)
|
||||
t->outtuple = listcount(out);
|
||||
t->intuple = listcount(in);
|
||||
|
||||
dowidth(t);
|
||||
checkwidth(t);
|
||||
return t;
|
||||
}
|
||||
|
||||
@ -201,6 +221,9 @@ addmethod(Node *n, Type *t, int local)
|
||||
Type *f, *d, *pa;
|
||||
Sym *st, *sf;
|
||||
|
||||
pa = nil;
|
||||
sf = nil;
|
||||
|
||||
// get field sym
|
||||
if(n == N)
|
||||
goto bad;
|
||||
@ -465,7 +488,7 @@ dostruct(Node *n, int et)
|
||||
|
||||
t = typ(et);
|
||||
stotype(n, &t->type);
|
||||
dowidth(t);
|
||||
checkwidth(t);
|
||||
return t;
|
||||
}
|
||||
|
||||
@ -484,12 +507,13 @@ dcopy(Sym *a, Sym *b)
|
||||
a->oconst = b->oconst;
|
||||
a->package = b->package;
|
||||
a->opackage = b->opackage;
|
||||
a->forwtype = b->forwtype;
|
||||
a->lexical = b->lexical;
|
||||
a->undef = b->undef;
|
||||
a->vargen = b->vargen;
|
||||
a->vblock = b->vblock;
|
||||
a->tblock = b->tblock;
|
||||
a->local = b->local;
|
||||
a->offset = b->offset;
|
||||
}
|
||||
|
||||
Sym*
|
||||
@ -639,14 +663,6 @@ addvar(Node *n, Type *t, int ctxt)
|
||||
fatal("addvar: n=%N t=%T nil", n, t);
|
||||
|
||||
s = n->sym;
|
||||
vargen++;
|
||||
gen = vargen;
|
||||
|
||||
r = autodcl;
|
||||
if(ctxt == PEXTERN) {
|
||||
r = externdcl;
|
||||
gen = 0;
|
||||
}
|
||||
|
||||
if(s->vblock == block) {
|
||||
if(s->oname != N) {
|
||||
@ -657,8 +673,16 @@ addvar(Node *n, Type *t, int ctxt)
|
||||
yyerror("var %S redeclared in this block", s);
|
||||
}
|
||||
|
||||
if(ctxt != PEXTERN)
|
||||
if(ctxt == PEXTERN) {
|
||||
r = externdcl;
|
||||
gen = 0;
|
||||
vargen++; // just for diffing output against old compiler
|
||||
} else {
|
||||
r = autodcl;
|
||||
vargen++;
|
||||
gen = vargen;
|
||||
pushdcl(s);
|
||||
}
|
||||
|
||||
s->vargen = gen;
|
||||
s->oname = n;
|
||||
@ -687,65 +711,34 @@ addvar(Node *n, Type *t, int ctxt)
|
||||
}
|
||||
|
||||
void
|
||||
addtyp(Type *n, Type *t, int ctxt)
|
||||
addtyp(Type *n, int ctxt)
|
||||
{
|
||||
Dcl *r, *d;
|
||||
Sym *s;
|
||||
Type *f, *ot;
|
||||
|
||||
if(n==T || n->sym == S || t == T)
|
||||
fatal("addtyp: n=%T t=%T nil", n, t);
|
||||
if(n==T || n->sym == S)
|
||||
fatal("addtyp: n=%T t=%T nil", n);
|
||||
|
||||
s = n->sym;
|
||||
|
||||
r = autodcl;
|
||||
if(ctxt == PEXTERN) {
|
||||
ot = s->otype;
|
||||
if(ot != T) {
|
||||
// allow nil interface to be
|
||||
// redeclared as an interface
|
||||
if(ot->etype == TINTER && ot->type == T && t->etype == TINTER) {
|
||||
if(dflag())
|
||||
print("forew typ-dcl %S G%ld %T\n", s, s->vargen, t);
|
||||
s->otype = t;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(ctxt == PEXTERN)
|
||||
r = externdcl;
|
||||
else {
|
||||
r = autodcl;
|
||||
pushdcl(s);
|
||||
}
|
||||
vargen++; // just for diffing output against old compiler
|
||||
|
||||
if(s->tblock == block)
|
||||
yyerror("type %S redeclared in this block %d", s, block);
|
||||
|
||||
if(ctxt != PEXTERN)
|
||||
pushdcl(s);
|
||||
|
||||
if(t->sym != S)
|
||||
warn("addtyp: renaming type %S/%lT to %S/%lT",
|
||||
t->sym, t->sym->otype, s, n);
|
||||
|
||||
vargen++;
|
||||
s->vargen = vargen;
|
||||
s->otype = t;
|
||||
s->otype = n;
|
||||
s->lexical = LATYPE;
|
||||
s->tblock = block;
|
||||
|
||||
t->sym = s;
|
||||
t->vargen = vargen;
|
||||
|
||||
if(s->forwtype != T) {
|
||||
dowidth(t);
|
||||
for(f=s->forwtype; f!=T; f=f->nforw) {
|
||||
if(!isptr[f->etype])
|
||||
fatal("addtyp: forward");
|
||||
f->type = t;
|
||||
}
|
||||
s->forwtype = T;
|
||||
}
|
||||
|
||||
d = dcl();
|
||||
d->dsym = s;
|
||||
d->dtype = t;
|
||||
d->dtype = n;
|
||||
d->op = OTYPE;
|
||||
|
||||
r->back->forw = d;
|
||||
@ -753,12 +746,50 @@ addtyp(Type *n, Type *t, int ctxt)
|
||||
|
||||
if(dflag()) {
|
||||
if(ctxt == PEXTERN)
|
||||
print("extern typ-dcl %S G%ld %T\n", s, s->vargen, t);
|
||||
print("extern typ-dcl %S G%ld %T\n", s, s->vargen, n);
|
||||
else
|
||||
print("auto typ-dcl %S G%ld %T\n", s, s->vargen, t);
|
||||
print("auto typ-dcl %S G%ld %T\n", s, s->vargen, n);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
addconst(Node *n, Node *e, int ctxt)
|
||||
{
|
||||
Sym *s;
|
||||
Dcl *r, *d;
|
||||
|
||||
if(n->op != ONAME)
|
||||
fatal("addconst: not a name");
|
||||
|
||||
if(e->op != OLITERAL) {
|
||||
yyerror("expression must be a constant");
|
||||
return;
|
||||
}
|
||||
|
||||
s = n->sym;
|
||||
|
||||
if(ctxt == PEXTERN)
|
||||
r = externdcl;
|
||||
else {
|
||||
r = autodcl;
|
||||
pushdcl(s);
|
||||
}
|
||||
|
||||
s->oconst = e;
|
||||
s->lexical = LACONST;
|
||||
|
||||
d = dcl();
|
||||
d->dsym = s;
|
||||
d->dnode = e;
|
||||
d->op = OCONST;
|
||||
|
||||
r->back->forw = d;
|
||||
r->back = d;
|
||||
|
||||
if(dflag())
|
||||
print("const-dcl %S %N\n", n->sym, n->sym->oconst);
|
||||
}
|
||||
|
||||
Node*
|
||||
fakethis(void)
|
||||
{
|
||||
@ -850,9 +881,6 @@ forwdcl(Sym *s)
|
||||
|
||||
t = typ(TFORW);
|
||||
t = ptrto(t);
|
||||
|
||||
t->nforw = s->forwtype;
|
||||
s->forwtype = t;
|
||||
return t;
|
||||
}
|
||||
|
||||
@ -1038,3 +1066,75 @@ fninit(Node *n)
|
||||
popdcl();
|
||||
compile(fn);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* when a type's width should be known, we call checkwidth
|
||||
* to compute it. during a declaration like
|
||||
*
|
||||
* type T *struct { next T }
|
||||
*
|
||||
* it is necessary to defer the calculation of the struct width
|
||||
* until after T has been initialized to be a pointer to that struct.
|
||||
* similarly, during import processing structs may be used
|
||||
* before their definition. in those situations, calling
|
||||
* defercheckwidth() stops width calculations until
|
||||
* resumecheckwidth() is called, at which point all the
|
||||
* checkwidths that were deferred are executed.
|
||||
* sometimes it is okay to
|
||||
*/
|
||||
typedef struct TypeList TypeList;
|
||||
struct TypeList {
|
||||
Type *t;
|
||||
TypeList *next;
|
||||
};
|
||||
|
||||
static TypeList *tlfree;
|
||||
static TypeList *tlq;
|
||||
static int defercalc;
|
||||
|
||||
void
|
||||
checkwidth(Type *t)
|
||||
{
|
||||
TypeList *l;
|
||||
|
||||
if(!defercalc) {
|
||||
dowidth(t);
|
||||
return;
|
||||
}
|
||||
|
||||
l = tlfree;
|
||||
if(l != nil)
|
||||
tlfree = l->next;
|
||||
else
|
||||
l = mal(sizeof *l);
|
||||
|
||||
l->t = t;
|
||||
l->next = tlq;
|
||||
tlq = l;
|
||||
}
|
||||
|
||||
void
|
||||
defercheckwidth(void)
|
||||
{
|
||||
if(defercalc)
|
||||
fatal("defercheckwidth");
|
||||
defercalc = 1;
|
||||
}
|
||||
|
||||
void
|
||||
resumecheckwidth(void)
|
||||
{
|
||||
TypeList *l, *next;
|
||||
|
||||
if(!defercalc)
|
||||
fatal("restartcheckwidth");
|
||||
defercalc = 0;
|
||||
|
||||
for(l = tlq; l != nil; l = tlq) {
|
||||
dowidth(l->t);
|
||||
tlq = l->next;
|
||||
l->next = tlfree;
|
||||
tlfree = l;
|
||||
}
|
||||
}
|
||||
|
@ -300,6 +300,7 @@ importvar(int export, Node *ss, Type *t)
|
||||
warn("redeclare import var %S from %T to %T",
|
||||
s, s->oname->type, t);
|
||||
}
|
||||
checkwidth(t);
|
||||
addvar(newname(s), t, PEXTERN);
|
||||
|
||||
if(debug['e'])
|
||||
@ -325,6 +326,7 @@ importtype(int export, Node *ss, Type *t)
|
||||
s->otype = typ(0);
|
||||
*s->otype = *t;
|
||||
s->otype->sym = s;
|
||||
checkwidth(s->otype);
|
||||
|
||||
if(debug['e'])
|
||||
print("import type %S %lT\n", s, t);
|
||||
@ -333,7 +335,7 @@ importtype(int export, Node *ss, Type *t)
|
||||
void
|
||||
importmethod(Sym *s, Type *t)
|
||||
{
|
||||
dowidth(t);
|
||||
checkwidth(t);
|
||||
addmethod(newname(s), t, 0);
|
||||
}
|
||||
|
||||
|
@ -146,9 +146,6 @@ struct Type
|
||||
// TFIELD
|
||||
Type* down; // also used in TMAP
|
||||
|
||||
// TPTR
|
||||
Type* nforw;
|
||||
|
||||
// TARRAY
|
||||
int32 bound; // negative is dynamic array
|
||||
};
|
||||
@ -215,7 +212,6 @@ struct Sym
|
||||
Node* oname; // ONAME node if a var
|
||||
Type* otype; // TYPE node if a type
|
||||
Node* oconst; // OLITERAL node if a const
|
||||
Type* forwtype; // TPTR iff forward declared
|
||||
vlong offset; // stack location if automatic
|
||||
int32 lexical;
|
||||
int32 vargen; // unique variable number
|
||||
@ -322,8 +318,10 @@ enum
|
||||
TFIELD,
|
||||
TANY,
|
||||
TSTRING,
|
||||
TFORWSTRUCT,
|
||||
TFORWINTER,
|
||||
|
||||
NTYPE, // 26
|
||||
NTYPE, // 28
|
||||
};
|
||||
enum
|
||||
{
|
||||
@ -624,7 +622,8 @@ int Zconv(Fmt*);
|
||||
* dcl.c
|
||||
*/
|
||||
void dodclvar(Node*, Type*);
|
||||
void dodcltype(Type*, Type*);
|
||||
Type* dodcltype(Type*);
|
||||
void updatetype(Type*, Type*);
|
||||
void dodclconst(Node*, Node*);
|
||||
void defaultlit(Node*);
|
||||
int listcount(Node*);
|
||||
@ -648,18 +647,21 @@ void markdclstack(void);
|
||||
void testdclstack(void);
|
||||
Sym* pushdcl(Sym*);
|
||||
void addvar(Node*, Type*, int);
|
||||
void addtyp(Type*, Type*, int);
|
||||
void addtyp(Type*, int);
|
||||
void addconst(Node*, Node*, int);
|
||||
Node* fakethis(void);
|
||||
Node* newname(Sym*);
|
||||
Node* oldname(Sym*);
|
||||
Type* newtype(Sym*);
|
||||
Type* oldtype(Sym*);
|
||||
Type* forwdcl(Sym*);
|
||||
void fninit(Node*);
|
||||
Node* nametoanondcl(Node*);
|
||||
Node* nametodcl(Node*, Type*);
|
||||
Node* anondcl(Type*);
|
||||
void checkarglist(Node*);
|
||||
void checkwidth(Type*);
|
||||
void defercheckwidth(void);
|
||||
void resumecheckwidth(void);
|
||||
|
||||
/*
|
||||
* export.c
|
||||
|
@ -48,6 +48,7 @@
|
||||
%type <node> fnres Afnres Bfnres fnliteral xfndcl fndcl fnbody
|
||||
%type <node> keyexpr_list keyval_list_r keyval
|
||||
%type <node> typedcl Atypedcl Btypedcl
|
||||
%type <type> typedclname
|
||||
|
||||
%type <type> fntype fnlitdcl Afntype Bfntype fullAtype
|
||||
%type <type> non_name_Atype non_name_type
|
||||
@ -137,16 +138,25 @@ import_package:
|
||||
}
|
||||
|
||||
import_there:
|
||||
hidden_import_list_r '$' '$'
|
||||
hidden_import_list '$' '$'
|
||||
{
|
||||
checkimports();
|
||||
unimportfile();
|
||||
}
|
||||
| LIMPORT '$' '$' hidden_import_list_r '$' '$'
|
||||
| LIMPORT '$' '$' hidden_import_list '$' '$'
|
||||
{
|
||||
checkimports();
|
||||
}
|
||||
|
||||
hidden_import_list:
|
||||
{
|
||||
defercheckwidth();
|
||||
}
|
||||
hidden_import_list_r
|
||||
{
|
||||
resumecheckwidth();
|
||||
}
|
||||
|
||||
/*
|
||||
* declarations
|
||||
*/
|
||||
@ -317,16 +327,37 @@ typedcl:
|
||||
Atypedcl
|
||||
| Btypedcl
|
||||
|
||||
Atypedcl:
|
||||
new_type fullAtype
|
||||
typedclname:
|
||||
new_type
|
||||
{
|
||||
dodcltype($1, $2);
|
||||
$$ = dodcltype($1);
|
||||
defercheckwidth();
|
||||
}
|
||||
|
||||
Btypedcl:
|
||||
new_type fullBtype
|
||||
Atypedcl:
|
||||
typedclname fullAtype
|
||||
{
|
||||
dodcltype($1, $2);
|
||||
updatetype($1, $2);
|
||||
resumecheckwidth();
|
||||
}
|
||||
| typedclname LSTRUCT
|
||||
{
|
||||
updatetype($1, typ(TFORWSTRUCT));
|
||||
resumecheckwidth();
|
||||
}
|
||||
/*
|
||||
| typedclname LINTERFACE
|
||||
{
|
||||
updatetype($1, typ(TFORWINTER));
|
||||
resumecheckwidth();
|
||||
}
|
||||
*/
|
||||
|
||||
Btypedcl:
|
||||
typedclname fullBtype
|
||||
{
|
||||
updatetype($1, $2);
|
||||
resumecheckwidth();
|
||||
}
|
||||
|
||||
else_stmt1:
|
||||
@ -991,7 +1022,6 @@ non_name_Atype:
|
||||
| interfacetype
|
||||
| '*' fullAtype
|
||||
{
|
||||
dowidth($2);
|
||||
$$ = ptrto($2);
|
||||
}
|
||||
|
||||
@ -1033,15 +1063,15 @@ Btype:
|
||||
}
|
||||
| '*' fullBtype
|
||||
{
|
||||
dowidth($2);
|
||||
$$ = ptrto($2);
|
||||
}
|
||||
| '*' lname
|
||||
{
|
||||
// dont know if this is an error or not
|
||||
if(dclcontext != PEXTERN)
|
||||
yyerror("forward type in function body %s", $2->name);
|
||||
$$ = forwdcl($2);
|
||||
Type *t;
|
||||
|
||||
t = dodcltype(newtype($2));
|
||||
updatetype(t, typ(TFORWSTRUCT));
|
||||
$$ = ptrto(t);
|
||||
}
|
||||
|
||||
Bchantype:
|
||||
@ -1721,7 +1751,7 @@ hidden_type1:
|
||||
}
|
||||
| '*' hidden_type
|
||||
{
|
||||
dowidth($2);
|
||||
checkwidth($2);
|
||||
$$ = ptrto($2);
|
||||
}
|
||||
| LCOMM LCHAN hidden_type
|
||||
@ -1823,7 +1853,7 @@ hidden_importsym:
|
||||
* to check whether the rest of the grammar is free of
|
||||
* reduce/reduce conflicts, comment this section out by
|
||||
* removing the slash on the next line.
|
||||
*
|
||||
*/
|
||||
lpack:
|
||||
LATYPE
|
||||
{
|
||||
@ -1867,6 +1897,5 @@ latype:
|
||||
yyerror("no type %s.%s", context, $3->name);
|
||||
YYERROR;
|
||||
}
|
||||
|
||||
/**/
|
||||
|
||||
|
@ -1543,7 +1543,7 @@ eqtype(Type *t1, Type *t2, int d)
|
||||
t1 = t1->type;
|
||||
t2 = t2->type;
|
||||
for(;;) {
|
||||
if(!eqtype(t1, t2, 0))
|
||||
if(!eqtype(t1, t2, d+1))
|
||||
return 0;
|
||||
if(t1 == T)
|
||||
return 1;
|
||||
|
@ -253,7 +253,7 @@ loop:
|
||||
if(n->type == T) {
|
||||
s = n->sym;
|
||||
if(s->undef == 0) {
|
||||
yyerror("walktype: %N undeclared", n);
|
||||
yyerror("walktype: %S undeclared", s);
|
||||
s->undef = 1;
|
||||
}
|
||||
}
|
||||
@ -334,7 +334,6 @@ loop:
|
||||
if(t == T)
|
||||
goto ret;
|
||||
|
||||
dowidth(t);
|
||||
if(n->left->op == ODOTMETH)
|
||||
n->op = OCALLMETH;
|
||||
if(n->left->op == ODOTINTER)
|
||||
@ -348,6 +347,7 @@ loop:
|
||||
goto ret;
|
||||
}
|
||||
|
||||
dowidth(t);
|
||||
n->type = *getoutarg(t);
|
||||
switch(t->outtuple) {
|
||||
case 0:
|
||||
|
@ -97,13 +97,6 @@ BUG: compilation succeeds incorrectly
|
||||
=========== bugs/bug093.go
|
||||
M
|
||||
|
||||
=========== bugs/bug094.go
|
||||
bugs/bug094.go:11: left side of := must be a name
|
||||
bad top
|
||||
. LITERAL-I0 l(81)
|
||||
bugs/bug094.go:11: fatal error: walktype: top=3 LITERAL
|
||||
BUG: fails incorrectly
|
||||
|
||||
=========== bugs/bug095.go
|
||||
found 2, expected 1
|
||||
|
||||
@ -232,7 +225,8 @@ fixedbugs/bug081.go:5: syntax error near x
|
||||
fixedbugs/bug086.go:5: function ends without a return statement
|
||||
|
||||
=========== fixedbugs/bug091.go
|
||||
fixedbugs/bug091.go:14: label exit not defined
|
||||
fixedbugs/bug091.go:15: c: undefined
|
||||
fixedbugs/bug091.go:15: fatal error: addvar: n=NAME-i G0 a(1) l(85) t=<T> nil
|
||||
|
||||
=========== fixedbugs/bug103.go
|
||||
fixedbugs/bug103.go:8: function requires a return type
|
||||
|
Loading…
Reference in New Issue
Block a user