// 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.

#include	<u.h>
#include	<libc.h>
#include	"go.h"
#include	"y.tab.h"

static	void	funcargs(Node*);
static	void	funcargs2(Type*);

static int
dflag(void)
{
	if(!debug['d'])
		return 0;
	if(debug['y'])
		return 1;
	if(incannedimport)
		return 0;
	return 1;
}

/*
 * declaration stack & operations
 */

static void
dcopy(Sym *a, Sym *b)
{
	a->pkg = b->pkg;
	a->name = b->name;
	a->def = b->def;
	a->block = b->block;
	a->lastlineno = b->lastlineno;
}

static Sym*
push(void)
{
	Sym *d;

	d = mal(sizeof(*d));
	d->lastlineno = lineno;
	d->link = dclstack;
	dclstack = d;
	return d;
}

static Sym*
pushdcl(Sym *s)
{
	Sym *d;

	d = push();
	dcopy(d, s);
	if(dflag())
		print("\t%L push %S %p\n", lineno, s, s->def);
	return d;
}

void
popdcl(void)
{
	Sym *d, *s;
	int lno;

//	if(dflag())
//		print("revert\n");

	for(d=dclstack; d!=S; d=d->link) {
		if(d->name == nil)
			break;
		s = pkglookup(d->name, d->pkg);
		lno = s->lastlineno;
		dcopy(s, d);
		d->lastlineno = lno;
		if(dflag())
			print("\t%L pop %S %p\n", lineno, s, s->def);
	}
	if(d == S)
		fatal("popdcl: no mark");
	dclstack = d->link;
	block = d->block;
}

void
poptodcl(void)
{
	// pop the old marker and push a new one
	// (cannot reuse the existing one)
	// because we use the markers to identify blocks
	// for the goto restriction checks.
	popdcl();
	markdcl();
}

void
markdcl(void)
{
	Sym *d;

	d = push();
	d->name = nil;		// used as a mark in fifo
	d->block = block;

	blockgen++;
	block = blockgen;

//	if(dflag())
//		print("markdcl\n");
}

void
dumpdcl(char *st)
{
	Sym *s, *d;
	int i;

	USED(st);

	i = 0;
	for(d=dclstack; d!=S; d=d->link) {
		i++;
		print("    %.2d %p", i, d);
		if(d->name == nil) {
			print("\n");
			continue;
		}
		print(" '%s'", d->name);
		s = pkglookup(d->name, d->pkg);
		print(" %S\n", s);
	}
}

void
testdclstack(void)
{
	Sym *d;

	for(d=dclstack; d!=S; d=d->link) {
		if(d->name == nil) {
			if(nerrors != 0)
				errorexit();
			yyerror("mark left on the stack");
			continue;
		}
	}
}

void
redeclare(Sym *s, char *where)
{
	Strlit *pkgstr;
	int line1, line2;

	if(s->lastlineno == 0) {
		pkgstr = s->origpkg ? s->origpkg->path : s->pkg->path;
		yyerror("%S redeclared %s\n"
			"\tprevious declaration during import \"%Z\"",
			s, where, pkgstr);
	} else {
		line1 = parserline();
		line2 = s->lastlineno;
		
		// When an import and a declaration collide in separate files,
		// present the import as the "redeclared", because the declaration
		// is visible where the import is, but not vice versa.
		// See issue 4510.
		if(s->def == N) {
			line2 = line1;
			line1 = s->lastlineno;
		}

		yyerrorl(line1, "%S redeclared %s\n"
			"\tprevious declaration at %L",
			s, where, line2);
	}
}

static int vargen;

/*
 * declare individual names - var, typ, const
 */
void
declare(Node *n, int ctxt)
{
	Sym *s;
	int gen;
	static int typegen;
	
	if(ctxt == PDISCARD)
		return;

	if(isblank(n))
		return;

	n->lineno = parserline();
	s = n->sym;

	// kludgy: typecheckok means we're past parsing.  Eg genwrapper may declare out of package names later.
	if(importpkg == nil && !typecheckok && s->pkg != localpkg)
		yyerror("cannot declare name %S", s);

	if(ctxt == PEXTERN && strcmp(s->name, "init") == 0)
		yyerror("cannot declare init - must be func", s);

	gen = 0;
	if(ctxt == PEXTERN) {
		externdcl = list(externdcl, n);
		if(dflag())
			print("\t%L global decl %S %p\n", lineno, s, n);
	} else {
		if(curfn == nil && ctxt == PAUTO)
			fatal("automatic outside function");
		if(curfn != nil)
			curfn->dcl = list(curfn->dcl, n);
		if(n->op == OTYPE)
			gen = ++typegen;
		else if(n->op == ONAME && ctxt == PAUTO && strstr(s->name, "·") == nil)
			gen = ++vargen;
		pushdcl(s);
		n->curfn = curfn;
	}
	if(ctxt == PAUTO)
		n->xoffset = 0;

	if(s->block == block) {
		// functype will print errors about duplicate function arguments.
		// Don't repeat the error here.
		if(ctxt != PPARAM && ctxt != PPARAMOUT)
			redeclare(s, "in this block");
	}

	s->block = block;
	s->lastlineno = parserline();
	s->def = n;
	n->vargen = gen;
	n->funcdepth = funcdepth;
	n->class = ctxt;

	autoexport(n, ctxt);
}

void
addvar(Node *n, Type *t, int ctxt)
{
	if(n==N || n->sym == S || (n->op != ONAME && n->op != ONONAME) || t == T)
		fatal("addvar: n=%N t=%T nil", n, t);

	n->op = ONAME;
	declare(n, ctxt);
	n->type = t;
}

/*
 * declare variables from grammar
 * new_name_list (type | [type] = expr_list)
 */
NodeList*
variter(NodeList *vl, Node *t, NodeList *el)
{
	int doexpr;
	Node *v, *e, *as2;
	NodeList *init;

	init = nil;
	doexpr = el != nil;

	if(count(el) == 1 && count(vl) > 1) {
		e = el->n;
		as2 = nod(OAS2, N, N);
		as2->list = vl;
		as2->rlist = list1(e);
		for(; vl; vl=vl->next) {
			v = vl->n;
			v->op = ONAME;
			declare(v, dclcontext);
			v->ntype = t;
			v->defn = as2;
			if(funcdepth > 0)
				init = list(init, nod(ODCL, v, N));
		}
		return list(init, as2);
	}
	
	for(; vl; vl=vl->next) {
		if(doexpr) {
			if(el == nil) {
				yyerror("missing expression in var declaration");
				break;
			}
			e = el->n;
			el = el->next;
		} else
			e = N;

		v = vl->n;
		v->op = ONAME;
		declare(v, dclcontext);
		v->ntype = t;

		if(e != N || funcdepth > 0 || isblank(v)) {
			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;
		}
	}
	if(el != nil)
		yyerror("extra expression in var declaration");
	return init;
}

/*
 * declare constants from grammar
 * new_name_list [[type] = expr_list]
 */
NodeList*
constiter(NodeList *vl, Node *t, NodeList *cl)
{
	Node *v, *c;
	NodeList *vv;

	vv = nil;
	if(cl == nil) {
		if(t != N)
			yyerror("const declaration cannot have type without expression");
		cl = lastconst;
		t = lasttype;
	} else {
		lastconst = cl;
		lasttype = t;
	}
	cl = listtreecopy(cl);

	for(; vl; vl=vl->next) {
		if(cl == nil) {
			yyerror("missing value in const declaration");
			break;
		}
		c = cl->n;
		cl = cl->next;

		v = vl->n;
		v->op = OLITERAL;
		declare(v, dclcontext);

		v->ntype = t;
		v->defn = c;

		vv = list(vv, nod(ODCLCONST, v, N));
	}
	if(cl != nil)
		yyerror("extra expression in const declaration");
	iota += 1;
	return vv;
}

/*
 * this generates a new name node,
 * typically for labels or other one-off names.
 */
Node*
newname(Sym *s)
{
	Node *n;

	if(s == S)
		fatal("newname nil");

	n = nod(ONAME, N, N);
	n->sym = s;
	n->type = T;
	n->addable = 1;
	n->ullman = 1;
	n->xoffset = 0;
	return n;
}

/*
 * this generates a new name node for a name
 * being declared.
 */
Node*
dclname(Sym *s)
{
	Node *n;

	n = newname(s);
	n->op = ONONAME;	// caller will correct it
	return n;
}

Node*
typenod(Type *t)
{
	// if we copied another type with *t = *u
	// then t->nod might be out of date, so
	// check t->nod->type too
	if(t->nod == N || t->nod->type != t) {
		t->nod = nod(OTYPE, N, N);
		t->nod->type = t;
		t->nod->sym = t->sym;
	}
	return t->nod;
}


/*
 * this will return an old name
 * that has already been pushed on the
 * declaration list. a diagnostic is
 * generated if no name has been defined.
 */
Node*
oldname(Sym *s)
{
	Node *n;
	Node *c;

	n = s->def;
	if(n == N) {
		// maybe a top-level name will come along
		// to give this a definition later.
		// walkdef will check s->def again once
		// all the input source has been processed.
		n = newname(s);
		n->op = ONONAME;
		n->iota = iota;	// save current iota value in const declarations
	}
	if(curfn != nil && n->funcdepth > 0 && n->funcdepth != funcdepth && n->op == ONAME) {
		// inner func is referring to var in outer func.
		//
		// TODO(rsc): If there is an outer variable x and we
		// are parsing x := 5 inside the closure, until we get to
		// the := it looks like a reference to the outer x so we'll
		// make x a closure variable unnecessarily.
		if(n->closure == N || n->closure->funcdepth != funcdepth) {
			// create new closure var.
			c = nod(ONAME, N, N);
			c->sym = s;
			c->class = PPARAMREF;
			c->isddd = n->isddd;
			c->defn = n;
			c->addable = 0;
			c->ullman = 2;
			c->funcdepth = funcdepth;
			c->outer = n->closure;
			n->closure = c;
			n->addrtaken = 1;
			c->closure = n;
			c->xoffset = 0;
			curfn->cvars = list(curfn->cvars, c);
		}
		// return ref to closure var, not original
		return n->closure;
	}
	return n;
}

/*
 * := declarations
 */

static int
colasname(Node *n)
{
	switch(n->op) {
	case ONAME:
	case ONONAME:
	case OPACK:
	case OTYPE:
	case OLITERAL:
		return n->sym != S;
	}
	return 0;
}

void
colasdefn(NodeList *left, Node *defn)
{
	int nnew, nerr;
	NodeList *l;
	Node *n;

	for(l=left; l; l=l->next)
		if(l->n->sym != S)
			l->n->sym->flags |= SymUniq;

	nnew = 0;
	nerr = 0;
	for(l=left; l; l=l->next) {
		n = l->n;
		if(isblank(n))
			continue;
		if(!colasname(n)) {
			yyerrorl(defn->lineno, "non-name %N on left side of :=", n);
			nerr++;
			continue;
		}
		if((n->sym->flags & SymUniq) == 0) {
			yyerrorl(defn->lineno, "%S repeated on left side of :=", n->sym);
			n->diag++;
			nerr++;
			continue;
		}
		n->sym->flags &= ~SymUniq;
		if(n->sym->block == block)
			continue;

		nnew++;
		n = newname(n->sym);
		declare(n, dclcontext);
		n->defn = defn;
		defn->ninit = list(defn->ninit, nod(ODCL, n, N));
		l->n = n;
	}
	if(nnew == 0 && nerr == 0)
		yyerrorl(defn->lineno, "no new variables on left side of :=");
}

Node*
colas(NodeList *left, NodeList *right, int32 lno)
{
	Node *as;

	as = nod(OAS2, N, N);
	as->list = left;
	as->rlist = right;
	as->colas = 1;
	as->lineno = lno;
	colasdefn(left, as);

	// make the tree prettier; not necessary
	if(count(left) == 1 && count(right) == 1) {
		as->left = as->list->n;
		as->right = as->rlist->n;
		as->list = nil;
		as->rlist = nil;
		as->op = OAS;
	}

	return as;
}

/*
 * declare the arguments in an
 * interface field declaration.
 */
void
ifacedcl(Node *n)
{
	if(n->op != ODCLFIELD || n->right == N)
		fatal("ifacedcl");

	if(isblank(n->left))
		yyerror("methods must have a unique non-blank name");

	dclcontext = PPARAM;
	markdcl();
	funcdepth++;
	n->outer = curfn;
	curfn = n;
	funcargs(n->right);

	// funcbody is normally called after the parser has
	// seen the body of a function but since an interface
	// field declaration does not have a body, we must
	// call it now to pop the current declaration context.
	dclcontext = PAUTO;
	funcbody(n);
}

/*
 * declare the function proper
 * and declare the arguments.
 * called in extern-declaration context
 * returns in auto-declaration context.
 */
void
funchdr(Node *n)
{
	// change the declaration context from extern to auto
	if(funcdepth == 0 && dclcontext != PEXTERN)
		fatal("funchdr: dclcontext");

	dclcontext = PAUTO;
	markdcl();
	funcdepth++;

	n->outer = curfn;
	curfn = n;

	if(n->nname)
		funcargs(n->nname->ntype);
	else if (n->ntype)
		funcargs(n->ntype);
	else
		funcargs2(n->type);
}

static void
funcargs(Node *nt)
{
	Node *n, *nn;
	NodeList *l;
	int gen;

	if(nt->op != OTFUNC)
		fatal("funcargs %O", nt->op);

	// re-start the variable generation number
	// we want to use small numbers for the return variables,
	// so let them have the chunk starting at 1.
	vargen = count(nt->rlist);

	// declare the receiver and in arguments.
	// no n->defn because type checking of func header
	// will not fill in the types until later
	if(nt->left != N) {
		n = nt->left;
		if(n->op != ODCLFIELD)
			fatal("funcargs receiver %O", n->op);
		if(n->left != N) {
			n->left->op = ONAME;
			n->left->ntype = n->right;
			declare(n->left, PPARAM);
			if(dclcontext == PAUTO)
				n->left->vargen = ++vargen;
		}
	}
	for(l=nt->list; l; l=l->next) {
		n = l->n;
		if(n->op != ODCLFIELD)
			fatal("funcargs in %O", n->op);
		if(n->left != N) {
			n->left->op = ONAME;
			n->left->ntype = n->right;
			declare(n->left, PPARAM);
			if(dclcontext == PAUTO)
				n->left->vargen = ++vargen;
		}
	}

	// declare the out arguments.
	gen = count(nt->list);
	int i = 0;
	for(l=nt->rlist; l; l=l->next) {
		n = l->n;

		if(n->op != ODCLFIELD)
			fatal("funcargs out %O", n->op);

		if(n->left == N) {
			// Name so that escape analysis can track it. ~r stands for 'result'.
			snprint(namebuf, sizeof(namebuf), "~r%d", gen++);
			n->left = newname(lookup(namebuf));
			// TODO: n->left->missing = 1;
		} 

		n->left->op = ONAME;

		if(isblank(n->left)) {
			// Give it a name so we can assign to it during return. ~b stands for 'blank'.
			// The name must be different from ~r above because if you have
			//	func f() (_ int)
			//	func g() int
			// f is allowed to use a plain 'return' with no arguments, while g is not.
			// So the two cases must be distinguished.
			// We do not record a pointer to the original node (n->orig).
			// Having multiple names causes too much confusion in later passes.
			nn = nod(OXXX, N, N);
			*nn = *n->left;
			nn->orig = nn;
			snprint(namebuf, sizeof(namebuf), "~b%d", gen++);
			nn->sym = lookup(namebuf);
			n->left = nn;
		}

		n->left->ntype = n->right;
		declare(n->left, PPARAMOUT);
		if(dclcontext == PAUTO)
			n->left->vargen = ++i;
	}
}

/*
 * Same as funcargs, except run over an already constructed TFUNC.
 * This happens during import, where the hidden_fndcl rule has
 * used functype directly to parse the function's type.
 */
static void
funcargs2(Type *t)
{
	Type *ft;
	Node *n;

	if(t->etype != TFUNC)
		fatal("funcargs2 %T", t);
	
	if(t->thistuple)
		for(ft=getthisx(t)->type; ft; ft=ft->down) {
			if(!ft->nname || !ft->nname->sym)
				continue;
			n = ft->nname;  // no need for newname(ft->nname->sym)
			n->type = ft->type;
			declare(n, PPARAM);
		}

	if(t->intuple)
		for(ft=getinargx(t)->type; ft; ft=ft->down) {
			if(!ft->nname || !ft->nname->sym)
				continue;
			n = ft->nname;
			n->type = ft->type;
			declare(n, PPARAM);
		}

	if(t->outtuple)
		for(ft=getoutargx(t)->type; ft; ft=ft->down) {
			if(!ft->nname || !ft->nname->sym)
				continue;
			n = ft->nname;
			n->type = ft->type;
			declare(n, PPARAMOUT);
		}
}

/*
 * finish the body.
 * called in auto-declaration context.
 * returns in extern-declaration context.
 */
void
funcbody(Node *n)
{
	// change the declaration context from auto to extern
	if(dclcontext != PAUTO)
		fatal("funcbody: dclcontext");
	popdcl();
	funcdepth--;
	curfn = n->outer;
	n->outer = N;
	if(funcdepth == 0)
		dclcontext = PEXTERN;
}

/*
 * new type being defined with name s.
 */
Node*
typedcl0(Sym *s)
{
	Node *n;

	n = newname(s);
	n->op = OTYPE;
	declare(n, dclcontext);
	return n;
}

/*
 * node n, which was returned by typedcl0
 * is being declared to have uncompiled type t.
 * return the ODCLTYPE node to use.
 */
Node*
typedcl1(Node *n, Node *t, int local)
{
	n->ntype = t;
	n->local = local;
	return nod(ODCLTYPE, n, N);
}

/*
 * structs, functions, and methods.
 * they don't belong here, but where do they belong?
 */

static void
checkembeddedtype(Type *t)
{
	if (t == T)
		return;

	if(t->sym == S && isptr[t->etype]) {
		t = t->type;
		if(t->etype == TINTER)
			yyerror("embedded type cannot be a pointer to interface");
	}
	if(isptr[t->etype])
		yyerror("embedded type cannot be a pointer");
	else if(t->etype == TFORW && t->embedlineno == 0)
		t->embedlineno = lineno;
}

static Type*
structfield(Node *n)
{
	Type *f;
	int lno;

	lno = lineno;
	lineno = n->lineno;

	if(n->op != ODCLFIELD)
		fatal("structfield: oops %N\n", n);

	f = typ(TFIELD);
	f->isddd = n->isddd;

	if(n->right != N) {
		typecheck(&n->right, Etype);
		n->type = n->right->type;
		if(n->left != N)
			n->left->type = n->type;
		if(n->embedded)
			checkembeddedtype(n->type);
	}
	n->right = N;
		
	f->type = n->type;
	if(f->type == T)
		f->broke = 1;

	switch(n->val.ctype) {
	case CTSTR:
		f->note = n->val.u.sval;
		break;
	default:
		yyerror("field annotation must be string");
		// fallthrough
	case CTxxx:
		f->note = nil;
		break;
	}

	if(n->left && n->left->op == ONAME) {
		f->nname = n->left;
		f->embedded = n->embedded;
		f->sym = f->nname->sym;
	}

	lineno = lno;
	return f;
}

static uint32 uniqgen;

static void
checkdupfields(Type *t, char* what)
{
	int lno;

	lno = lineno;

	for( ; t; t=t->down) {
		if(t->sym && t->nname && !isblank(t->nname)) {
			if(t->sym->uniqgen == uniqgen) {
				lineno = t->nname->lineno;
				yyerror("duplicate %s %s", what, t->sym->name);
			} else
				t->sym->uniqgen = uniqgen;
		}
	}

	lineno = lno;
}

/*
 * convert a parsed id/type list into
 * a type for struct/interface/arglist
 */
Type*
tostruct(NodeList *l)
{
	Type *t, *f, **tp;
	t = typ(TSTRUCT);

	for(tp = &t->type; l; l=l->next) {
		f = structfield(l->n);

		*tp = f;
		tp = &f->down;
	}

	for(f=t->type; f && !t->broke; f=f->down)
		if(f->broke)
			t->broke = 1;

	uniqgen++;
	checkdupfields(t->type, "field");

	if (!t->broke)
		checkwidth(t);

	return t;
}

static Type*
tofunargs(NodeList *l)
{
	Type *t, *f, **tp;

	t = typ(TSTRUCT);
	t->funarg = 1;

	for(tp = &t->type; l; l=l->next) {
		f = structfield(l->n);
		f->funarg = 1;

		// esc.c needs to find f given a PPARAM to add the tag.
		if(l->n->left && l->n->left->class == PPARAM)
			l->n->left->paramfld = f;

		*tp = f;
		tp = &f->down;
	}

	for(f=t->type; f && !t->broke; f=f->down)
		if(f->broke)
			t->broke = 1;

	return t;
}

static Type*
interfacefield(Node *n)
{
	Type *f;
	int lno;

	lno = lineno;
	lineno = n->lineno;

	if(n->op != ODCLFIELD)
		fatal("interfacefield: oops %N\n", n);

	if (n->val.ctype != CTxxx)
		yyerror("interface method cannot have annotation");

	f = typ(TFIELD);
	f->isddd = n->isddd;
	
	if(n->right != N) {
		if(n->left != N) {
			// queue resolution of method type for later.
			// right now all we need is the name list.
			// avoids cycles for recursive interface types.
			n->type = typ(TINTERMETH);
			n->type->nname = n->right;
			n->left->type = n->type;
			queuemethod(n);

			if(n->left->op == ONAME) {
				f->nname = n->left;
				f->embedded = n->embedded;
				f->sym = f->nname->sym;
			}

		} else {

			typecheck(&n->right, Etype);
			n->type = n->right->type;

			if(n->embedded)
				checkembeddedtype(n->type);

			if(n->type)
				switch(n->type->etype) {
				case TINTER:
					break;
				case TFORW:
					yyerror("interface type loop involving %T", n->type);
					f->broke = 1;
					break;
				default:
					yyerror("interface contains embedded non-interface %T", n->type);
					f->broke = 1;
					break;
				}
		}
	}

	n->right = N;
	
	f->type = n->type;
	if(f->type == T)
		f->broke = 1;
	
	lineno = lno;
	return f;
}

Type*
tointerface(NodeList *l)
{
	Type *t, *f, **tp, *t1;

	t = typ(TINTER);

	tp = &t->type;
	for(; l; l=l->next) {
		f = interfacefield(l->n);

		if (l->n->left == N && f->type->etype == TINTER) {
			// embedded interface, inline methods
			for(t1=f->type->type; t1; t1=t1->down) {
				f = typ(TFIELD);
				f->type = t1->type;
				f->broke = t1->broke;
				f->sym = t1->sym;
				if(f->sym)
					f->nname = newname(f->sym);
				*tp = f;
				tp = &f->down;
			}
		} else {
			*tp = f;
			tp = &f->down;
		}
	}

	for(f=t->type; f && !t->broke; f=f->down)
		if(f->broke)
			t->broke = 1;

	uniqgen++;
	checkdupfields(t->type, "method");
	t = sortinter(t);
	checkwidth(t);

	return t;
}

Node*
embedded(Sym *s, Pkg *pkg)
{
	Node *n;
	char *name;

	// Names sometimes have disambiguation junk
	// appended after a center dot.  Discard it when
	// making the name for the embedded struct field.
	enum { CenterDot = 0xB7 };
	name = s->name;
	if(utfrune(s->name, CenterDot)) {
		name = strdup(s->name);
		*utfrune(name, CenterDot) = 0;
	}

	if(exportname(name))
		n = newname(lookup(name));
	else if(s->pkg == builtinpkg)
		// The name of embedded builtins belongs to pkg.
		n = newname(pkglookup(name, pkg));
	else
		n = newname(pkglookup(name, s->pkg));
	n = nod(ODCLFIELD, n, oldname(s));
	n->embedded = 1;
	return n;
}

/*
 * check that the list of declarations is either all anonymous or all named
 */

static Node*
findtype(NodeList *l)
{
	for(; l; l=l->next)
		if(l->n->op == OKEY)
			return l->n->right;
	return N;
}

NodeList*
checkarglist(NodeList *all, int input)
{
	int named;
	Node *n, *t, *nextt;
	NodeList *l;

	named = 0;
	for(l=all; l; l=l->next) {
		if(l->n->op == OKEY) {
			named = 1;
			break;
		}
	}
	if(named) {
		n = N;
		for(l=all; l; l=l->next) {
			n = l->n;
			if(n->op != OKEY && n->sym == S) {
				yyerror("mixed named and unnamed function parameters");
				break;
			}
		}
		if(l == nil && n != N && n->op != OKEY)
			yyerror("final function parameter must have type");
	}

	nextt = nil;
	for(l=all; l; l=l->next) {
		// can cache result from findtype to avoid
		// quadratic behavior here, but unlikely to matter.
		n = l->n;
		if(named) {
			if(n->op == OKEY) {
				t = n->right;
				n = n->left;
				nextt = nil;
			} else {
				if(nextt == nil)
					nextt = findtype(l);
				t = nextt;
			}
		} else {
			t = n;
			n = N;
		}

		// during import l->n->op is OKEY, but l->n->left->sym == S
		// means it was a '?', not that it was
		// a lone type This doesn't matter for the exported
		// declarations, which are parsed by rules that don't
		// use checkargs, but can happen for func literals in
		// the inline bodies.
		// TODO(rsc) this can go when typefmt case TFIELD in exportmode fmt.c prints _ instead of ?
		if(importpkg && n->sym == S)
			n = N;

		if(n != N && n->sym == S) {
			t = n;
			n = N;
		}
		if(n != N)
			n = newname(n->sym);
		n = nod(ODCLFIELD, n, t);
		if(n->right != N && n->right->op == ODDD) {
			if(!input)
				yyerror("cannot use ... in output argument list");
			else if(l->next != nil)
				yyerror("can only use ... as final argument in list");
			n->right->op = OTARRAY;
			n->right->right = n->right->left;
			n->right->left = N;
			n->isddd = 1;
			if(n->left != N)
				n->left->isddd = 1;
		}
		l->n = n;
	}
	return all;
}


Node*
fakethis(void)
{
	Node *n;

	n = nod(ODCLFIELD, N, typenod(ptrto(typ(TSTRUCT))));
	return n;
}

/*
 * Is this field a method on an interface?
 * Those methods have an anonymous
 * *struct{} as the receiver.
 * (See fakethis above.)
 */
int
isifacemethod(Type *f)
{
	Type *rcvr;
	Type *t;

	rcvr = getthisx(f)->type;
	if(rcvr->sym != S)
		return 0;
	t = rcvr->type;
	if(!isptr[t->etype])
		return 0;
	t = t->type;
	if(t->sym != S || t->etype != TSTRUCT || t->type != T)
		return 0;
	return 1;
}

/*
 * turn a parsed function declaration
 * into a type
 */
Type*
functype(Node *this, NodeList *in, NodeList *out)
{
	Type *t;
	NodeList *rcvr;
	Sym *s;

	t = typ(TFUNC);

	rcvr = nil;
	if(this)
		rcvr = list1(this);
	t->type = tofunargs(rcvr);
	t->type->down = tofunargs(out);
	t->type->down->down = tofunargs(in);

	uniqgen++;
	checkdupfields(t->type->type, "argument");
	checkdupfields(t->type->down->type, "argument");
	checkdupfields(t->type->down->down->type, "argument");

	if (t->type->broke || t->type->down->broke || t->type->down->down->broke)
		t->broke = 1;

	if(this)
		t->thistuple = 1;
	t->outtuple = count(out);
	t->intuple = count(in);
	t->outnamed = 0;
	if(t->outtuple > 0 && out->n->left != N && out->n->left->orig != N) {
		s = out->n->left->orig->sym;
		if(s != S && (s->name[0] != '~' || s->name[1] != 'r')) // ~r%d is the name invented for an unnamed result
			t->outnamed = 1;
	}

	return t;
}

Sym*
methodsym(Sym *nsym, Type *t0, int iface)
{
	Sym *s;
	char *p;
	Type *t;
	char *suffix;
	Pkg *spkg;
	static Pkg *toppkg;

	t = t0;
	if(t == T)
		goto bad;
	s = t->sym;
	if(s == S && isptr[t->etype]) {
		t = t->type;
		if(t == T)
			goto bad;
		s = t->sym;
	}
	spkg = nil;
	if(s != S)
		spkg = s->pkg;

	// if t0 == *t and t0 has a sym,
	// we want to see *t, not t0, in the method name.
	if(t != t0 && t0->sym)
		t0 = ptrto(t);

	suffix = "";
	if(iface) {
		dowidth(t0);
		if(t0->width < types[tptr]->width)
			suffix = "·i";
	}
	if((spkg == nil || nsym->pkg != spkg) && !exportname(nsym->name)) {
		if(t0->sym == S && isptr[t0->etype])
			p = smprint("(%-hT).%s.%s%s", t0, nsym->pkg->prefix, nsym->name, suffix);
		else
			p = smprint("%-hT.%s.%s%s", t0, nsym->pkg->prefix, nsym->name, suffix);
	} else {
		if(t0->sym == S && isptr[t0->etype])
			p = smprint("(%-hT).%s%s", t0, nsym->name, suffix);
		else
			p = smprint("%-hT.%s%s", t0, nsym->name, suffix);
	}
	if(spkg == nil) {
		if(toppkg == nil)
			toppkg = mkpkg(strlit("go"));
		spkg = toppkg;
	}
	s = pkglookup(p, spkg);
	free(p);
	return s;

bad:
	yyerror("illegal receiver type: %T", t0);
	return S;
}

Node*
methodname(Node *n, Type *t)
{
	Sym *s;

	s = methodsym(n->sym, t, 0);
	if(s == S)
		return n;
	return newname(s);
}

Node*
methodname1(Node *n, Node *t)
{
	char *star;
	char *p;

	star = nil;
	if(t->op == OIND) {
		star = "*";
		t = t->left;
	}
	if(t->sym == S || isblank(n))
		return newname(n->sym);

	if(star)
		p = smprint("(%s%S).%S", star, t->sym, n->sym);
	else
		p = smprint("%S.%S", t->sym, n->sym);

	if(exportname(t->sym->name))
		n = newname(lookup(p));
	else
		n = newname(pkglookup(p, t->sym->pkg));
	free(p);
	return n;
}

/*
 * add a method, declared as a function,
 * n is fieldname, pa is base type, t is function type
 */
void
addmethod(Sym *sf, Type *t, int local, int nointerface)
{
	Type *f, *d, *pa;
	Node *n;

	// get field sym
	if(sf == S)
		fatal("no method symbol");

	// get parent type sym
	pa = getthisx(t)->type;	// ptr to this structure
	if(pa == T) {
		yyerror("missing receiver");
		return;
	}

	pa = pa->type;
	f = methtype(pa, 1);
	if(f == T) {
		t = pa;
		if(t == T) // rely on typecheck having complained before
			return;
		if(t != T) {
			if(isptr[t->etype]) {
				if(t->sym != S) {
					yyerror("invalid receiver type %T (%T is a pointer type)", pa, t);
					return;
				}
				t = t->type;
			}
			if(t->broke) // rely on typecheck having complained before
				return;
			if(t->sym == S) {
				yyerror("invalid receiver type %T (%T is an unnamed type)", pa, t);
				return;
			}
			if(isptr[t->etype]) {
				yyerror("invalid receiver type %T (%T is a pointer type)", pa, t);
				return;
			}
			if(t->etype == TINTER) {
				yyerror("invalid receiver type %T (%T is an interface type)", pa, t);
				return;
			}
		}
		// Should have picked off all the reasons above,
		// but just in case, fall back to generic error.
		yyerror("invalid receiver type %T (%lT / %lT)", pa, pa, t);
		return;
	}

	pa = f;
	if(pa->etype == TSTRUCT) {
		for(f=pa->type; f; f=f->down) {
			if(f->sym == sf) {
				yyerror("type %T has both field and method named %S", pa, sf);
				return;
			}
		}
	}

	if(local && !pa->local) {
		// defining method on non-local type.
		yyerror("cannot define new methods on non-local type %T", pa);
		return;
	}

	n = nod(ODCLFIELD, newname(sf), N);
	n->type = t;

	d = T;	// last found
	for(f=pa->method; f!=T; f=f->down) {
		d = f;
		if(f->etype != TFIELD)
			fatal("addmethod: not TFIELD: %N", f);
		if(strcmp(sf->name, f->sym->name) != 0)
			continue;
		if(!eqtype(t, f->type))
			yyerror("method redeclared: %T.%S\n\t%T\n\t%T", pa, sf, f->type, t);
		return;
	}

	f = structfield(n);
	f->nointerface = nointerface;

	// during import unexported method names should be in the type's package
	if(importpkg && f->sym && !exportname(f->sym->name) && f->sym->pkg != structpkg)
		fatal("imported method name %+S in wrong package %s\n", f->sym, structpkg->name);

	if(d == T)
		pa->method = f;
	else
		d->down = f;
	return;
}

void
funccompile(Node *n, int isclosure)
{
	stksize = BADWIDTH;
	maxarg = 0;

	if(n->type == T) {
		if(nerrors == 0)
			fatal("funccompile missing type");
		return;
	}

	// assign parameter offsets
	checkwidth(n->type);
	
	// record offset to actual frame pointer.
	// for closure, have to skip over leading pointers and PC slot.
	// TODO(rsc): this is the old jit closure handling code.
	// with the new closures, isclosure is always 0; delete this block.
	nodfp->xoffset = 0;
	if(isclosure) {
		NodeList *l;
		for(l=n->nname->ntype->list; l; l=l->next) {
			nodfp->xoffset += widthptr;
			if(l->n->left == N)	// found slot for PC
				break;
		}
	}

	if(curfn)
		fatal("funccompile %S inside %S", n->nname->sym, curfn->nname->sym);

	stksize = 0;
	dclcontext = PAUTO;
	funcdepth = n->funcdepth + 1;
	compile(n);
	curfn = nil;
	funcdepth = 0;
	dclcontext = PEXTERN;
}

Sym*
funcsym(Sym *s)
{
	char *p;
	Sym *s1;
	
	p = smprint("%s·f", s->name);
	s1 = pkglookup(p, s->pkg);
	free(p);
	if(s1->def == N) {
		s1->def = newname(s1);
		s1->def->shortname = newname(s);
		funcsyms = list(funcsyms, s1->def);
	}
	return s1;
}
