2009-05-21 14:46:07 -06:00
|
|
|
// Copyright 2009 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.
|
|
|
|
|
2009-08-03 12:58:52 -06:00
|
|
|
/*
|
|
|
|
* static initialization
|
|
|
|
*/
|
|
|
|
|
2009-05-21 14:46:07 -06:00
|
|
|
#include "go.h"
|
|
|
|
|
2009-08-12 14:18:19 -06:00
|
|
|
static void
|
|
|
|
init1(Node *n, NodeList **out)
|
|
|
|
{
|
|
|
|
NodeList *l;
|
|
|
|
|
|
|
|
if(n == N)
|
|
|
|
return;
|
|
|
|
init1(n->left, out);
|
|
|
|
init1(n->right, out);
|
|
|
|
for(l=n->list; l; l=l->next)
|
|
|
|
init1(l->n, out);
|
|
|
|
|
|
|
|
if(n->op != ONAME)
|
|
|
|
return;
|
|
|
|
switch(n->class) {
|
|
|
|
case PEXTERN:
|
|
|
|
case PFUNC:
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(n->initorder == 1)
|
|
|
|
return;
|
|
|
|
if(n->initorder == 2)
|
|
|
|
fatal("init loop");
|
|
|
|
|
|
|
|
// make sure that everything n depends on is initialized.
|
|
|
|
// n->defn is an assignment to n
|
|
|
|
n->initorder = 2;
|
|
|
|
if(n->defn != N) {
|
|
|
|
switch(n->defn->op) {
|
2009-08-30 15:43:33 -06:00
|
|
|
default:
|
|
|
|
goto bad;
|
|
|
|
|
2009-08-12 14:18:19 -06:00
|
|
|
case ODCLFUNC:
|
|
|
|
for(l=n->defn->nbody; l; l=l->next)
|
|
|
|
init1(l->n, out);
|
|
|
|
break;
|
2009-08-30 15:43:33 -06:00
|
|
|
|
2009-08-12 14:18:19 -06:00
|
|
|
case OAS:
|
2009-08-30 15:43:33 -06:00
|
|
|
if(n->defn->left != n)
|
|
|
|
goto bad;
|
2009-08-12 14:18:19 -06:00
|
|
|
init1(n->defn->right, out);
|
|
|
|
if(debug['j'])
|
|
|
|
print("%S\n", n->sym);
|
|
|
|
*out = list(*out, n->defn);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
n->initorder = 1;
|
|
|
|
return;
|
2009-08-30 15:43:33 -06:00
|
|
|
|
|
|
|
bad:
|
|
|
|
dump("defn", n->defn);
|
|
|
|
fatal("bad defn");
|
2009-08-12 14:18:19 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
initreorder(NodeList *l, NodeList **out)
|
|
|
|
{
|
|
|
|
Node *n;
|
|
|
|
|
|
|
|
for(; l; l=l->next) {
|
|
|
|
n = l->n;
|
|
|
|
switch(n->op) {
|
|
|
|
case ODCLFUNC:
|
|
|
|
case ODCLCONST:
|
|
|
|
case ODCLTYPE:
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
initreorder(n->ninit, out);
|
|
|
|
n->ninit = nil;
|
|
|
|
init1(n, out);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-07-17 02:00:44 -06:00
|
|
|
NodeList*
|
|
|
|
initfix(NodeList *l)
|
2009-05-21 14:46:07 -06:00
|
|
|
{
|
2009-08-30 15:43:33 -06:00
|
|
|
NodeList *lout;
|
2009-05-21 14:46:07 -06:00
|
|
|
|
2009-08-30 15:43:33 -06:00
|
|
|
lout = nil;
|
|
|
|
initreorder(l, &lout);
|
|
|
|
return lout;
|
2009-05-21 14:46:07 -06:00
|
|
|
}
|