// inner func is referring to var
// in outer func.
if(n->closure == N || n->closure->funcdepth != funcdepth) {
+ typecheck(&n, Erv);
// create new closure var.
c = nod(ONAME, N, N);
c->sym = s;
* new_name_list (type | [type] = expr_list)
*/
NodeList*
-variter(NodeList *vl, Node *nt, NodeList *el)
+variter(NodeList *vl, Node *t, NodeList *el)
{
- int doexpr, lno;
- Node *v, *e, *a;
- Type *tv;
- NodeList *r;
- Type *t;
-
- t = T;
- if(nt) {
- typecheck(&nt, Etype);
- t = nt->type;
- }
+ int doexpr, gen;
+ Node *v, *e;
+ NodeList *init;
+ Sym *s;
+ Dcl *r, *d;
- r = nil;
+ init = nil;
doexpr = el != nil;
for(; vl; vl=vl->next) {
if(doexpr) {
break;
}
e = el->n;
+ el = el->next;
} else
e = N;
v = vl->n;
- tv = t;
- if(e) {
- lno = lineno;
- lineno = v->lineno;
- typecheck(&e, Erv);
- defaultlit(&e, t);
- if(t)
- e = typecheckconv(nil, e, t, 0);
- if(tv == nil)
- tv = e->type;
- if(tv && tv->etype == TNIL) {
- yyerror("cannot initialize %#N to untyped nil", v);
- tv = nil;
- }
- lineno = lno;
+ s = v->sym;
+ if(dclcontext == PEXTERN || dclcontext == PFUNC) {
+ r = externdcl;
+ gen = 0;
+ } else {
+ r = autodcl;
+ gen = ++vargen;
+ pushdcl(s);
}
- a = N;
- if((e != N && tv != T) || funcdepth > 0)
- a = nod(OAS, v, e);
- dodclvar(v, tv, &r);
- if(a != N)
- r = list(r, a);
- if(el) {
- el->n = e;
- el = el->next;
+ redeclare("variable", s);
+ s->def = v;
+ // TODO: vargen
+ s->offset = 0;
+ s->block = block;
+
+ v->op = ONAME;
+ v->class = dclcontext;
+ v->ntype = t;
+ v->funcdepth = funcdepth;
+ v->vargen = gen;
+ if(e != N || funcdepth > 0) {
+ if(funcdepth > 0)
+ init = list(init, nod(ODCL, v, N));
+ e = nod(OAS, v, e);
+ init = list(init, e);
+ if(e->right != N)
+ v->defn = e;
}
+
+ d = dcl();
+ d->dsym = s;
+ d->dnode = v;
+ d->op = ONAME;
+ r->back->forw = d;
+ r->back = d;
+
+ autoexport(s);
}
if(el != nil)
yyerror("extra expr in var dcl");
- return r;
+ return init;
}
/*
n->type = types[TINT];
return n;
}
+
+void
+dclchecks(void)
+{
+ Dcl *d;
+
+ for(d=externdcl; d!=D; d=d->forw) {
+ if(d->op != ONAME)
+ continue;
+ typecheck(&d->dnode, Erv);
+ }
+}
Type *t;
n = s->def;
+ typecheck(&n, Erv);
if(n == N || n->op != OLITERAL)
fatal("dumpexportconst: oconst nil: %S", s);
Type *t;
n = s->def;
+ typecheck(&n, Erv);
if(n == N || n->type == T) {
yyerror("variable exported but not defined: %S", s);
return;
if(n->class != PAUTO)
continue;
+ typecheck(&n, Erv);
dowidth(n->type);
w = n->type->width;
if(n->class & PHEAP)
case OFOR:
sbreak = breakpc;
- p1 = gjmp(P); // goto test
+ p1 = gjmp(P); // goto test
breakpc = gjmp(P); // break: goto done
scontin = continpc;
continpc = pc;
if(n->ntest != N)
if(n->ntest->ninit != nil)
genlist(n->ntest->ninit);
- bgen(n->ntest, 0, p2); // if(!test) goto p2
+ bgen(n->ntest, 0, p2); // if(!test) goto p2
genlist(n->nbody); // then
p3 = gjmp(P); // goto done
patch(p2, pc); // else:
case OSWITCH:
sbreak = breakpc;
- p1 = gjmp(P); // goto test
+ p1 = gjmp(P); // goto test
breakpc = gjmp(P); // break: goto done
// define break label
case OSELECT:
sbreak = breakpc;
- p1 = gjmp(P); // goto test
+ p1 = gjmp(P); // goto test
breakpc = gjmp(P); // break: goto done
// define break label
Node* funclit0(Node*);
Node* funclit1(Node*, NodeList*);
Node* unsafenmagic(Node*, NodeList*);
+void dclchecks(void);
/*
* sinit.c
{
if(debug['f'])
frame(1);
+ typechecklist($4, Etop);
if(nerrors == 0)
fninit($4);
if(nsyntaxerrors == 0)
testdclstack();
+ dclchecks();
}
package:
$$ = $2;
if(yylast == LSEMIBRACE)
yyoptsemi(0);
- // walkdeflist($2);
}
| LVAR '(' vardcl_list osemi ')'
{
$$ = $3;
yyoptsemi(0);
- // walkdeflist($3);
}
| LVAR '(' ')'
{
n->val = e->val;
n->type = e->type;
break;
+
+ case ONAME:
+ if(n->ntype != N) {
+ typecheck(&n->ntype, Etype);
+ n->type = n->ntype->type;
+ if(n->type == T) {
+ n->diag = 1;
+ goto ret;
+ }
+ n->ntype = N;
+ }
+ if(n->type != T)
+ break;
+ if(n->defn == N)
+ fatal("var without type, init: %S", n->sym);
+ switch(n->defn->op) {
+ default:
+ fatal("walkdef name defn");
+ case OAS:
+ typecheck(&n->defn->right, Erv);
+ defaultlit(&n->defn->right, T);
+ if((t = n->defn->right->type) == T) {
+ n->diag = 1;
+ goto ret;
+ }
+ n->type = t;
+ break;
+ }
+ break;
}
ret:
if(!colasname(l))
goto allnew;
- if(l->sym->block == block) {
- if(!eqtype(l->type, t))
- goto allnew;
+ if(l->sym->block == block)
nred++;
- }
ntot++;
}
{
// change of type for f
i, f, s := f3(); // GCCGO_ERROR "previous"
- f, g, t := f3(); // ERROR "redeclared|redefinition"
+ f, g, t := f3(); // ERROR "redeclared|redefinition|cannot assign"
}
{
// change of type for i
i, f, s := f3(); // GCCGO_ERROR "previous"
- j, i, t := f3(); // ERROR "redeclared|redefinition"
+ j, i, t := f3(); // ERROR "redeclared|redefinition|cannot assign"
}
{
// no new variables