// 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	"md5.h"
#include	"y.tab.h"
#include	"yerr.h"

typedef struct Error Error;
struct Error
{
	int lineno;
	int seq;
	char *msg;
};
static Error *err;
static int nerr;
static int merr;

void
errorexit(void)
{
	flusherrors();
	if(outfile)
		remove(outfile);
	exits("error");
}

extern int yychar;
int
parserline(void)
{
	if(yychar != 0 && yychar != -2)	// parser has one symbol lookahead
		return prevlineno;
	return lineno;
}

static void
adderr(int line, char *fmt, va_list arg)
{
	Fmt f;
	Error *p;

	fmtstrinit(&f);
	fmtprint(&f, "%L: ", line);
	fmtvprint(&f, fmt, arg);
	fmtprint(&f, "\n");

	if(nerr >= merr) {
		if(merr == 0)
			merr = 16;
		else
			merr *= 2;
		p = realloc(err, merr*sizeof err[0]);
		if(p == nil) {
			merr = nerr;
			flusherrors();
			print("out of memory\n");
			errorexit();
		}
		err = p;
	}
	err[nerr].seq = nerr;
	err[nerr].lineno = line;
	err[nerr].msg = fmtstrflush(&f);
	nerr++;
}

static int
errcmp(const void *va, const void *vb)
{
	Error *a, *b;

	a = (Error*)va;
	b = (Error*)vb;
	if(a->lineno != b->lineno)
		return a->lineno - b->lineno;
	if(a->seq != b->seq)
		return a->seq - b->seq;
	return strcmp(a->msg, b->msg);
}

void
flusherrors(void)
{
	int i;

	if(nerr == 0)
		return;
	qsort(err, nerr, sizeof err[0], errcmp);
	for(i=0; i<nerr; i++)
		if(i==0 || strcmp(err[i].msg, err[i-1].msg) != 0)
			print("%s", err[i].msg);
	nerr = 0;
}

static void
hcrash(void)
{
	if(debug['h']) {
		flusherrors();
		if(outfile)
			remove(outfile);
		*(volatile int*)0 = 0;
	}
}

void
yyerrorl(int line, char *fmt, ...)
{
	va_list arg;

	va_start(arg, fmt);
	adderr(line, fmt, arg);
	va_end(arg);

	hcrash();
	nerrors++;
	if(nsavederrors+nerrors >= 10 && !debug['e']) {
		flusherrors();
		print("%L: too many errors\n", line);
		errorexit();
	}
}

extern int yystate, yychar;

void
yyerror(char *fmt, ...)
{
	int i;
	static int lastsyntax;
	va_list arg;
	char buf[512], *p;

	if(strncmp(fmt, "syntax error", 12) == 0) {
		nsyntaxerrors++;
		
		if(debug['x'])	
			print("yyerror: yystate=%d yychar=%d\n", yystate, yychar);

		// only one syntax error per line
		if(lastsyntax == lexlineno)
			return;
		lastsyntax = lexlineno;
		
		if(strstr(fmt, "{ or {")) {
			// The grammar has { and LBRACE but both show up as {.
			// Rewrite syntax error referring to "{ or {" to say just "{".
			strecpy(buf, buf+sizeof buf, fmt);
			p = strstr(buf, "{ or {");
			if(p)
				memmove(p+1, p+6, strlen(p+6)+1);
			fmt = buf;
		}
		
		// look for parse state-specific errors in list (see go.errors).
		for(i=0; i<nelem(yymsg); i++) {
			if(yymsg[i].yystate == yystate && yymsg[i].yychar == yychar) {
				yyerrorl(lexlineno, "syntax error: %s", yymsg[i].msg);
				return;
			}
		}
		
		// plain "syntax error" gets "near foo" added
		if(strcmp(fmt, "syntax error") == 0) {
			yyerrorl(lexlineno, "syntax error near %s", lexbuf);
			return;
		}
		
		// if bison says "syntax error, more info"; print "syntax error: more info".
		if(fmt[12] == ',') {
			yyerrorl(lexlineno, "syntax error:%s", fmt+13);
			return;
		}

		yyerrorl(lexlineno, "%s", fmt);
		return;
	}

	va_start(arg, fmt);
	adderr(parserline(), fmt, arg);
	va_end(arg);

	hcrash();
	nerrors++;
	if(nsavederrors+nerrors >= 10 && !debug['e']) {
		flusherrors();
		print("%L: too many errors\n", parserline());
		errorexit();
	}
}

void
warn(char *fmt, ...)
{
	va_list arg;

	va_start(arg, fmt);
	adderr(parserline(), fmt, arg);
	va_end(arg);

	hcrash();
}

void
warnl(int line, char *fmt, ...)
{
	va_list arg;

	va_start(arg, fmt);
	adderr(line, fmt, arg);
	va_end(arg);
}

void
fatal(char *fmt, ...)
{
	va_list arg;

	flusherrors();

	print("%L: internal compiler error: ", lineno);
	va_start(arg, fmt);
	vfprint(1, fmt, arg);
	va_end(arg);
	print("\n");
	
	// If this is a released compiler version, ask for a bug report.
	if(strncmp(getgoversion(), "release", 7) == 0) {
		print("\n");
		print("Please file a bug report including a short program that triggers the error.\n");
		print("http://code.google.com/p/go/issues/entry?template=compilerbug\n");
	}
	hcrash();
	errorexit();
}

void
linehist(char *file, int32 off, int relative)
{
	Hist *h;
	char *cp;

	if(debug['i']) {
		if(file != nil) {
			if(off < 0)
				print("pragma %s", file);
			else
			if(off > 0)
				print("line %s", file);
			else
				print("import %s", file);
		} else
			print("end of import");
		print(" at line %L\n", lexlineno);
	}

	if(off < 0 && file[0] != '/' && !relative) {
		cp = mal(strlen(file) + strlen(pathname) + 2);
		sprint(cp, "%s/%s", pathname, file);
		file = cp;
	}

	h = mal(sizeof(Hist));
	h->name = file;
	h->line = lexlineno;
	h->offset = off;
	h->link = H;
	if(ehist == H) {
		hist = h;
		ehist = h;
		return;
	}
	ehist->link = h;
	ehist = h;
}

int32
setlineno(Node *n)
{
	int32 lno;

	lno = lineno;
	if(n != N)
	switch(n->op) {
	case ONAME:
	case OTYPE:
	case OPACK:
	case OLITERAL:
		break;
	default:
		lineno = n->lineno;
		if(lineno == 0) {
			if(debug['K'])
				warn("setlineno: line 0");
			lineno = lno;
		}
	}
	return lno;
}

uint32
stringhash(char *p)
{
	int32 h;
	int c;

	h = 0;
	for(;;) {
		c = *p++;
		if(c == 0)
			break;
		h = h*PRIME1 + c;
	}

	if(h < 0) {
		h = -h;
		if(h < 0)
			h = 0;
	}
	return h;
}

Sym*
lookup(char *name)
{
	return pkglookup(name, localpkg);
}

Sym*
pkglookup(char *name, Pkg *pkg)
{
	Sym *s;
	uint32 h;
	int c;

	h = stringhash(name) % NHASH;
	c = name[0];
	for(s = hash[h]; s != S; s = s->link) {
		if(s->name[0] != c || s->pkg != pkg)
			continue;
		if(strcmp(s->name, name) == 0)
			return s;
	}

	s = mal(sizeof(*s));
	s->name = mal(strlen(name)+1);
	strcpy(s->name, name);

	s->pkg = pkg;

	s->link = hash[h];
	hash[h] = s;
	s->lexical = LNAME;

	return s;
}

Sym*
restrictlookup(char *name, Pkg *pkg)
{
	if(!exportname(name) && pkg != localpkg)
		yyerror("cannot refer to unexported name %s.%s", pkg->name, name);
	return pkglookup(name, pkg);
}


// find all the exported symbols in package opkg
// and make them available in the current package
void
importdot(Pkg *opkg, Node *pack)
{
	Sym *s, *s1;
	uint32 h;
	int n;

	n = 0;
	for(h=0; h<NHASH; h++) {
		for(s = hash[h]; s != S; s = s->link) {
			if(s->pkg != opkg)
				continue;
			if(s->def == N)
				continue;
			if(!exportname(s->name) || utfrune(s->name, 0xb7))	// 0xb7 = center dot
				continue;
			s1 = lookup(s->name);
			if(s1->def != N) {
				redeclare(s1, "during import");
				continue;
			}
			s1->def = s->def;
			s1->block = s->block;
			s1->def->pack = pack;
			n++;
		}
	}
	if(n == 0) {
		// can't possibly be used - there were no symbols
		yyerrorl(pack->lineno, "imported and not used: \"%Z\"", opkg->path);
	}
}

static void
gethunk(void)
{
	char *h;
	int32 nh;

	nh = NHUNK;
	if(thunk >= 10L*NHUNK)
		nh = 10L*NHUNK;
	h = (char*)malloc(nh);
	if(h == nil) {
		flusherrors();
		yyerror("out of memory");
		errorexit();
	}
	hunk = h;
	nhunk = nh;
	thunk += nh;
}

void*
mal(int32 n)
{
	void *p;

	if(n >= NHUNK) {
		p = malloc(n);
		if(p == nil) {
			flusherrors();
			yyerror("out of memory");
			errorexit();
		}
		memset(p, 0, n);
		return p;
	}

	while((uintptr)hunk & MAXALIGN) {
		hunk++;
		nhunk--;
	}
	if(nhunk < n)
		gethunk();

	p = hunk;
	nhunk -= n;
	hunk += n;
	memset(p, 0, n);
	return p;
}

void*
remal(void *p, int32 on, int32 n)
{
	void *q;

	q = (uchar*)p + on;
	if(q != hunk || nhunk < n) {
		if(on+n >= NHUNK) {
			q = mal(on+n);
			memmove(q, p, on);
			return q;
		}
		if(nhunk < on+n)
			gethunk();
		memmove(hunk, p, on);
		p = hunk;
		hunk += on;
		nhunk -= on;
	}
	hunk += n;
	nhunk -= n;
	return p;
}

Node*
nod(int op, Node *nleft, Node *nright)
{
	Node *n;

	n = mal(sizeof(*n));
	n->op = op;
	n->left = nleft;
	n->right = nright;
	n->lineno = parserline();
	n->xoffset = BADWIDTH;
	n->orig = n;
	n->curfn = curfn;
	return n;
}

int
algtype1(Type *t, Type **bad)
{
	int a, ret;
	Type *t1;
	
	if(bad)
		*bad = T;

	switch(t->etype) {
	case TINT8:
	case TUINT8:
	case TINT16:
	case TUINT16:
	case TINT32:
	case TUINT32:
	case TINT64:
	case TUINT64:
	case TINT:
	case TUINT:
	case TUINTPTR:
	case TBOOL:
	case TPTR32:
	case TPTR64:
	case TCHAN:
	case TUNSAFEPTR:
		return AMEM;

	case TFUNC:
	case TMAP:
		if(bad)
			*bad = t;
		return ANOEQ;

	case TFLOAT32:
		return AFLOAT32;

	case TFLOAT64:
		return AFLOAT64;

	case TCOMPLEX64:
		return ACPLX64;

	case TCOMPLEX128:
		return ACPLX128;

	case TSTRING:
		return ASTRING;
	
	case TINTER:
		if(isnilinter(t))
			return ANILINTER;
		return AINTER;
	
	case TARRAY:
		if(isslice(t)) {
			if(bad)
				*bad = t;
			return ANOEQ;
		}
		if(t->bound == 0)
			return AMEM;
		a = algtype1(t->type, bad);
		if(a == ANOEQ || a == AMEM) {
			if(a == ANOEQ && bad)
				*bad = t;
			return a;
		}
		return -1;  // needs special compare

	case TSTRUCT:
		if(t->type != T && t->type->down == T) {
			// One-field struct is same as that one field alone.
			return algtype1(t->type->type, bad);
		}
		ret = AMEM;
		for(t1=t->type; t1!=T; t1=t1->down) {
			a = algtype1(t1->type, bad);
			if(a == ANOEQ)
				return ANOEQ;  // not comparable
			if(a != AMEM)
				ret = -1;  // needs special compare
		}
		return ret;
	}

	fatal("algtype1: unexpected type %T", t);
	return 0;
}

int
algtype(Type *t)
{
	int a;
	
	a = algtype1(t, nil);
	if(a == AMEM || a == ANOEQ) {
		if(isslice(t))
			return ASLICE;
		switch(t->width) {
		case 0:
			return a + AMEM0 - AMEM;
		case 1:
			return a + AMEM8 - AMEM;
		case 2:
			return a + AMEM16 - AMEM;
		case 4:
			return a + AMEM32 - AMEM;
		case 8:
			return a + AMEM64 - AMEM;
		case 16:
			return a + AMEM128 - AMEM;
		}
	}
	return a;
}

Type*
maptype(Type *key, Type *val)
{
	Type *t;

	if(key != nil) {
		switch(key->etype) {
		default:
			if(algtype1(key, nil) == ANOEQ)
				yyerror("invalid map key type %T", key);
			break;
		case TANY:
			// will be resolved later.
			break;
		case TFORW:
			// map[key] used during definition of key.
			// postpone check until key is fully defined.
			// if there are multiple uses of map[key]
			// before key is fully defined, the error
			// will only be printed for the first one.
			// good enough.
			if(key->maplineno == 0)
				key->maplineno = lineno;
			break;
		}
	}
	t = typ(TMAP);
	t->down = key;
	t->type = val;
	return t;
}

Type*
typ(int et)
{
	Type *t;

	t = mal(sizeof(*t));
	t->etype = et;
	t->width = BADWIDTH;
	t->lineno = lineno;
	t->orig = t;
	return t;
}

static int
methcmp(const void *va, const void *vb)
{
	Type *a, *b;
	int i;
	
	a = *(Type**)va;
	b = *(Type**)vb;
	i = strcmp(a->sym->name, b->sym->name);
	if(i != 0)
		return i;
	if(!exportname(a->sym->name)) {
		i = strcmp(a->sym->pkg->path->s, b->sym->pkg->path->s);
		if(i != 0)
			return i;
	}
	return 0;
}

Type*
sortinter(Type *t)
{
	Type *f;
	int i;
	Type **a;
	
	if(t->type == nil || t->type->down == nil)
		return t;

	i=0;
	for(f=t->type; f; f=f->down)
		i++;
	a = mal(i*sizeof f);
	i = 0;
	for(f=t->type; f; f=f->down)
		a[i++] = f;
	qsort(a, i, sizeof a[0], methcmp);
	while(i-- > 0) {
		a[i]->down = f;
		f = a[i];
	}
	t->type = f;
	return t;
}

Node*
nodintconst(int64 v)
{
	Node *c;

	c = nod(OLITERAL, N, N);
	c->addable = 1;
	c->val.u.xval = mal(sizeof(*c->val.u.xval));
	mpmovecfix(c->val.u.xval, v);
	c->val.ctype = CTINT;
	c->type = types[TIDEAL];
	ullmancalc(c);
	return c;
}

Node*
nodfltconst(Mpflt* v)
{
	Node *c;

	c = nod(OLITERAL, N, N);
	c->addable = 1;
	c->val.u.fval = mal(sizeof(*c->val.u.fval));
	mpmovefltflt(c->val.u.fval, v);
	c->val.ctype = CTFLT;
	c->type = types[TIDEAL];
	ullmancalc(c);
	return c;
}

void
nodconst(Node *n, Type *t, int64 v)
{
	memset(n, 0, sizeof(*n));
	n->op = OLITERAL;
	n->addable = 1;
	ullmancalc(n);
	n->val.u.xval = mal(sizeof(*n->val.u.xval));
	mpmovecfix(n->val.u.xval, v);
	n->val.ctype = CTINT;
	n->type = t;

	if(isfloat[t->etype])
		fatal("nodconst: bad type %T", t);
}

Node*
nodnil(void)
{
	Node *c;

	c = nodintconst(0);
	c->val.ctype = CTNIL;
	c->type = types[TNIL];
	return c;
}

Node*
nodbool(int b)
{
	Node *c;

	c = nodintconst(0);
	c->val.ctype = CTBOOL;
	c->val.u.bval = b;
	c->type = idealbool;
	return c;
}

Type*
aindex(Node *b, Type *t)
{
	Type *r;
	int bound;

	bound = -1;	// open bound
	typecheck(&b, Erv);
	if(b != nil) {
		switch(consttype(b)) {
		default:
			yyerror("array bound must be an integer expression");
			break;
		case CTINT:
		case CTRUNE:
			bound = mpgetfix(b->val.u.xval);
			if(bound < 0)
				yyerror("array bound must be non negative");
			break;
		}
	}

	// fixed array
	r = typ(TARRAY);
	r->type = t;
	r->bound = bound;
	return r;
}

Node*
treecopy(Node *n)
{
	Node *m;

	if(n == N)
		return N;

	switch(n->op) {
	default:
		m = nod(OXXX, N, N);
		*m = *n;
		m->left = treecopy(n->left);
		m->right = treecopy(n->right);
		m->list = listtreecopy(n->list);
		if(m->defn)
			abort();
		break;

	case ONONAME:
		if(n->sym == lookup("iota")) {
			// Not sure yet whether this is the real iota,
			// but make a copy of the Node* just in case,
			// so that all the copies of this const definition
			// don't have the same iota value.
			m = nod(OXXX, N, N);
			*m = *n;
			m->iota = iota;
			break;
		}
		// fall through
	case ONAME:
	case OLITERAL:
	case OTYPE:
		m = n;
		break;
	}
	return m;
}


int
isnil(Node *n)
{
	if(n == N)
		return 0;
	if(n->op != OLITERAL)
		return 0;
	if(n->val.ctype != CTNIL)
		return 0;
	return 1;
}

int
isptrto(Type *t, int et)
{
	if(t == T)
		return 0;
	if(!isptr[t->etype])
		return 0;
	t = t->type;
	if(t == T)
		return 0;
	if(t->etype != et)
		return 0;
	return 1;
}

int
istype(Type *t, int et)
{
	return t != T && t->etype == et;
}

int
isfixedarray(Type *t)
{
	return t != T && t->etype == TARRAY && t->bound >= 0;
}

int
isslice(Type *t)
{
	return t != T && t->etype == TARRAY && t->bound < 0;
}

int
isblank(Node *n)
{
	char *p;

	if(n == N || n->sym == S)
		return 0;
	p = n->sym->name;
	if(p == nil)
		return 0;
	return p[0] == '_' && p[1] == '\0';
}

int
isinter(Type *t)
{
	return t != T && t->etype == TINTER;
}

int
isnilinter(Type *t)
{
	if(!isinter(t))
		return 0;
	if(t->type != T)
		return 0;
	return 1;
}

int
isideal(Type *t)
{
	if(t == T)
		return 0;
	if(t == idealstring || t == idealbool)
		return 1;
	switch(t->etype) {
	case TNIL:
	case TIDEAL:
		return 1;
	}
	return 0;
}

/*
 * given receiver of type t (t == r or t == *r)
 * return type to hang methods off (r).
 */
Type*
methtype(Type *t)
{
	if(t == T)
		return T;

	// strip away pointer if it's there
	if(isptr[t->etype]) {
		if(t->sym != S)
			return T;
		t = t->type;
		if(t == T)
			return T;
	}

	// need a type name
	if(t->sym == S)
		return T;

	// check types
	if(!issimple[t->etype])
	switch(t->etype) {
	default:
		return T;
	case TSTRUCT:
	case TARRAY:
	case TMAP:
	case TCHAN:
	case TSTRING:
	case TFUNC:
		break;
	}

	return t;
}

int
cplxsubtype(int et)
{
	switch(et) {
	case TCOMPLEX64:
		return TFLOAT32;
	case TCOMPLEX128:
		return TFLOAT64;
	}
	fatal("cplxsubtype: %E\n", et);
	return 0;
}

static int
eqnote(Strlit *a, Strlit *b)
{
	if(a == b)
		return 1;
	if(a == nil || b == nil)
		return 0;
	if(a->len != b->len)
		return 0;
	return memcmp(a->s, b->s, a->len) == 0;
}

typedef struct TypePairList TypePairList;
struct TypePairList
{
	Type *t1;
	Type *t2;
	TypePairList *next;
};

static int
onlist(TypePairList *l, Type *t1, Type *t2) 
{
	for(; l; l=l->next)
		if((l->t1 == t1 && l->t2 == t2) || (l->t1 == t2 && l->t2 == t1))
			return 1;
	return 0;
}

static int eqtype1(Type*, Type*, TypePairList*);

// Return 1 if t1 and t2 are identical, following the spec rules.
//
// Any cyclic type must go through a named type, and if one is
// named, it is only identical to the other if they are the same
// pointer (t1 == t2), so there's no chance of chasing cycles
// ad infinitum, so no need for a depth counter.
int
eqtype(Type *t1, Type *t2)
{
	return eqtype1(t1, t2, nil);
}

static int
eqtype1(Type *t1, Type *t2, TypePairList *assumed_equal)
{
	TypePairList l;

	if(t1 == t2)
		return 1;
	if(t1 == T || t2 == T || t1->etype != t2->etype)
		return 0;
	if(t1->sym || t2->sym) {
		// Special case: we keep byte and uint8 separate
		// for error messages.  Treat them as equal.
		switch(t1->etype) {
		case TUINT8:
			if((t1 == types[TUINT8] || t1 == bytetype) && (t2 == types[TUINT8] || t2 == bytetype))
				return 1;
			break;
		case TINT:
		case TINT32:
			if((t1 == types[runetype->etype] || t1 == runetype) && (t2 == types[runetype->etype] || t2 == runetype))
				return 1;
			break;
		}
		return 0;
	}

	if(onlist(assumed_equal, t1, t2))
		return 1;
	l.next = assumed_equal;
	l.t1 = t1;
	l.t2 = t2;

	switch(t1->etype) {
	case TINTER:
	case TSTRUCT:
		for(t1=t1->type, t2=t2->type; t1 && t2; t1=t1->down, t2=t2->down) {
			if(t1->etype != TFIELD || t2->etype != TFIELD)
				fatal("struct/interface missing field: %T %T", t1, t2);
			if(t1->sym != t2->sym || t1->embedded != t2->embedded || !eqtype1(t1->type, t2->type, &l) || !eqnote(t1->note, t2->note))
				goto no;
		}
		if(t1 == T && t2 == T)
			goto yes;
		goto no;

	case TFUNC:
		// Loop over structs: receiver, in, out.
		for(t1=t1->type, t2=t2->type; t1 && t2; t1=t1->down, t2=t2->down) {
			Type *ta, *tb;

			if(t1->etype != TSTRUCT || t2->etype != TSTRUCT)
				fatal("func missing struct: %T %T", t1, t2);

			// Loop over fields in structs, ignoring argument names.
			for(ta=t1->type, tb=t2->type; ta && tb; ta=ta->down, tb=tb->down) {
				if(ta->etype != TFIELD || tb->etype != TFIELD)
					fatal("func struct missing field: %T %T", ta, tb);
				if(ta->isddd != tb->isddd || !eqtype1(ta->type, tb->type, &l))
					goto no;
			}
			if(ta != T || tb != T)
				goto no;
		}
		if(t1 == T && t2 == T)
			goto yes;
		goto no;
	
	case TARRAY:
		if(t1->bound != t2->bound)
			goto no;
		break;
	
	case TCHAN:
		if(t1->chan != t2->chan)
			goto no;
		break;
	}

	if(eqtype1(t1->down, t2->down, &l) && eqtype1(t1->type, t2->type, &l))
		goto yes;
	goto no;

yes:
	assumed_equal = l.next;
	return 1;

no:
	assumed_equal = l.next;
	return 0;
}

// Are t1 and t2 equal struct types when field names are ignored?
// For deciding whether the result struct from g can be copied
// directly when compiling f(g()).
int
eqtypenoname(Type *t1, Type *t2)
{
	if(t1 == T || t2 == T || t1->etype != TSTRUCT || t2->etype != TSTRUCT)
		return 0;

	t1 = t1->type;
	t2 = t2->type;
	for(;;) {
		if(!eqtype(t1, t2))
			return 0;
		if(t1 == T)
			return 1;
		t1 = t1->down;
		t2 = t2->down;
	}
}

// Is type src assignment compatible to type dst?
// If so, return op code to use in conversion.
// If not, return 0.
int
assignop(Type *src, Type *dst, char **why)
{
	Type *missing, *have;
	int ptr;

	if(why != nil)
		*why = "";

	// TODO(rsc,lvd): This behaves poorly in the presence of inlining.
	// https://code.google.com/p/go/issues/detail?id=2795
	if(safemode && importpkg == nil && src != T && src->etype == TUNSAFEPTR) {
		yyerror("cannot use unsafe.Pointer");
		errorexit();
	}

	if(src == dst)
		return OCONVNOP;
	if(src == T || dst == T || src->etype == TFORW || dst->etype == TFORW || src->orig == T || dst->orig == T)
		return 0;

	// 1. src type is identical to dst.
	if(eqtype(src, dst))
		return OCONVNOP;
	
	// 2. src and dst have identical underlying types
	// and either src or dst is not a named type or
	// both are interface types.
	if(eqtype(src->orig, dst->orig) && (src->sym == S || dst->sym == S || src->etype == TINTER))
		return OCONVNOP;

	// 3. dst is an interface type and src implements dst.
	if(dst->etype == TINTER && src->etype != TNIL) {
		if(implements(src, dst, &missing, &have, &ptr))
			return OCONVIFACE;

		// we'll have complained about this method anyway, supress spurious messages.
		if(have && have->sym == missing->sym && (have->type->broke || missing->type->broke))
			return OCONVIFACE;

		if(why != nil) {
			if(isptrto(src, TINTER))
				*why = smprint(":\n\t%T is pointer to interface, not interface", src);
			else if(have && have->sym == missing->sym)
				*why = smprint(":\n\t%T does not implement %T (wrong type for %S method)\n"
					"\t\thave %S%hhT\n\t\twant %S%hhT", src, dst, missing->sym,
					have->sym, have->type, missing->sym, missing->type);
			else if(ptr)
				*why = smprint(":\n\t%T does not implement %T (%S method requires pointer receiver)",
					src, dst, missing->sym);
			else if(have)
				*why = smprint(":\n\t%T does not implement %T (missing %S method)\n"
					"\t\thave %S%hhT\n\t\twant %S%hhT", src, dst, missing->sym,
					have->sym, have->type, missing->sym, missing->type);
			else
				*why = smprint(":\n\t%T does not implement %T (missing %S method)",
					src, dst, missing->sym);
		}
		return 0;
	}
	if(isptrto(dst, TINTER)) {
		if(why != nil)
			*why = smprint(":\n\t%T is pointer to interface, not interface", dst);
		return 0;
	}
	if(src->etype == TINTER && dst->etype != TBLANK) {
		if(why != nil)
			*why = ": need type assertion";
		return 0;
	}

	// 4. src is a bidirectional channel value, dst is a channel type,
	// src and dst have identical element types, and
	// either src or dst is not a named type.
	if(src->etype == TCHAN && src->chan == Cboth && dst->etype == TCHAN)
	if(eqtype(src->type, dst->type) && (src->sym == S || dst->sym == S))
		return OCONVNOP;

	// 5. src is the predeclared identifier nil and dst is a nillable type.
	if(src->etype == TNIL) {
		switch(dst->etype) {
		case TARRAY:
			if(dst->bound != -100)	// not slice
				break;
		case TPTR32:
		case TPTR64:
		case TFUNC:
		case TMAP:
		case TCHAN:
		case TINTER:
			return OCONVNOP;
		}
	}

	// 6. rule about untyped constants - already converted by defaultlit.
	
	// 7. Any typed value can be assigned to the blank identifier.
	if(dst->etype == TBLANK)
		return OCONVNOP;

	return 0;
}

// Can we convert a value of type src to a value of type dst?
// If so, return op code to use in conversion (maybe OCONVNOP).
// If not, return 0.
int
convertop(Type *src, Type *dst, char **why)
{
	int op;
	
	if(why != nil)
		*why = "";

	if(src == dst)
		return OCONVNOP;
	if(src == T || dst == T)
		return 0;
	
	// 1. src can be assigned to dst.
	if((op = assignop(src, dst, why)) != 0)
		return op;

	// The rules for interfaces are no different in conversions
	// than assignments.  If interfaces are involved, stop now
	// with the good message from assignop.
	// Otherwise clear the error.
	if(src->etype == TINTER || dst->etype == TINTER)
		return 0;
	if(why != nil)
		*why = "";

	// 2. src and dst have identical underlying types.
	if(eqtype(src->orig, dst->orig))
		return OCONVNOP;
	
	// 3. src and dst are unnamed pointer types 
	// and their base types have identical underlying types.
	if(isptr[src->etype] && isptr[dst->etype] && src->sym == S && dst->sym == S)
	if(eqtype(src->type->orig, dst->type->orig))
		return OCONVNOP;

	// 4. src and dst are both integer or floating point types.
	if((isint[src->etype] || isfloat[src->etype]) && (isint[dst->etype] || isfloat[dst->etype])) {
		if(simtype[src->etype] == simtype[dst->etype])
			return OCONVNOP;
		return OCONV;
	}

	// 5. src and dst are both complex types.
	if(iscomplex[src->etype] && iscomplex[dst->etype]) {
		if(simtype[src->etype] == simtype[dst->etype])
			return OCONVNOP;
		return OCONV;
	}

	// 6. src is an integer or has type []byte or []rune
	// and dst is a string type.
	if(isint[src->etype] && dst->etype == TSTRING)
		return ORUNESTR;

	if(isslice(src) && dst->etype == TSTRING) {
		if(src->type->etype == bytetype->etype)
			return OARRAYBYTESTR;
		if(src->type->etype == runetype->etype)
			return OARRAYRUNESTR;
	}
	
	// 7. src is a string and dst is []byte or []rune.
	// String to slice.
	if(src->etype == TSTRING && isslice(dst)) {
		if(dst->type->etype == bytetype->etype)
			return OSTRARRAYBYTE;
		if(dst->type->etype == runetype->etype)
			return OSTRARRAYRUNE;
	}
	
	// 8. src is a pointer or uintptr and dst is unsafe.Pointer.
	if((isptr[src->etype] || src->etype == TUINTPTR) && dst->etype == TUNSAFEPTR)
		return OCONVNOP;

	// 9. src is unsafe.Pointer and dst is a pointer or uintptr.
	if(src->etype == TUNSAFEPTR && (isptr[dst->etype] || dst->etype == TUINTPTR))
		return OCONVNOP;

	return 0;
}

// Convert node n for assignment to type t.
Node*
assignconv(Node *n, Type *t, char *context)
{
	int op;
	Node *r, *old;
	char *why;
	
	if(n == N || n->type == T)
		return n;

	old = n;
	old->diag++;  // silence errors about n; we'll issue one below
	defaultlit(&n, t);
	old->diag--;
	if(t->etype == TBLANK)
		return n;

	if(eqtype(n->type, t))
		return n;

	op = assignop(n->type, t, &why);
	if(op == 0) {
		yyerror("cannot use %lN as type %T in %s%s", n, t, context, why);
		op = OCONV;
	}

	r = nod(op, n, N);
	r->type = t;
	r->typecheck = 1;
	r->implicit = 1;
	return r;
}

static int
subtype(Type **stp, Type *t, int d)
{
	Type *st;

loop:
	st = *stp;
	if(st == T)
		return 0;

	d++;
	if(d >= 10)
		return 0;

	switch(st->etype) {
	default:
		return 0;

	case TPTR32:
	case TPTR64:
	case TCHAN:
	case TARRAY:
		stp = &st->type;
		goto loop;

	case TANY:
		if(!st->copyany)
			return 0;
		*stp = t;
		break;

	case TMAP:
		if(subtype(&st->down, t, d))
			break;
		stp = &st->type;
		goto loop;

	case TFUNC:
		for(;;) {
			if(subtype(&st->type, t, d))
				break;
			if(subtype(&st->type->down->down, t, d))
				break;
			if(subtype(&st->type->down, t, d))
				break;
			return 0;
		}
		break;

	case TSTRUCT:
		for(st=st->type; st!=T; st=st->down)
			if(subtype(&st->type, t, d))
				return 1;
		return 0;
	}
	return 1;
}

/*
 * Is this a 64-bit type?
 */
int
is64(Type *t)
{
	if(t == T)
		return 0;
	switch(simtype[t->etype]) {
	case TINT64:
	case TUINT64:
	case TPTR64:
		return 1;
	}
	return 0;
}

/*
 * Is a conversion between t1 and t2 a no-op?
 */
int
noconv(Type *t1, Type *t2)
{
	int e1, e2;

	e1 = simtype[t1->etype];
	e2 = simtype[t2->etype];

	switch(e1) {
	case TINT8:
	case TUINT8:
		return e2 == TINT8 || e2 == TUINT8;

	case TINT16:
	case TUINT16:
		return e2 == TINT16 || e2 == TUINT16;

	case TINT32:
	case TUINT32:
	case TPTR32:
		return e2 == TINT32 || e2 == TUINT32 || e2 == TPTR32;

	case TINT64:
	case TUINT64:
	case TPTR64:
		return e2 == TINT64 || e2 == TUINT64 || e2 == TPTR64;

	case TFLOAT32:
		return e2 == TFLOAT32;

	case TFLOAT64:
		return e2 == TFLOAT64;
	}
	return 0;
}

void
argtype(Node *on, Type *t)
{
	dowidth(t);
	if(!subtype(&on->type, t, 0))
		fatal("argtype: failed %N %T\n", on, t);
}

Type*
shallow(Type *t)
{
	Type *nt;

	if(t == T)
		return T;
	nt = typ(0);
	*nt = *t;
	if(t->orig == t)
		nt->orig = nt;
	return nt;
}

static Type*
deep(Type *t)
{
	Type *nt, *xt;

	if(t == T)
		return T;

	switch(t->etype) {
	default:
		nt = t;	// share from here down
		break;

	case TANY:
		nt = shallow(t);
		nt->copyany = 1;
		break;

	case TPTR32:
	case TPTR64:
	case TCHAN:
	case TARRAY:
		nt = shallow(t);
		nt->type = deep(t->type);
		break;

	case TMAP:
		nt = shallow(t);
		nt->down = deep(t->down);
		nt->type = deep(t->type);
		break;

	case TFUNC:
		nt = shallow(t);
		nt->type = deep(t->type);
		nt->type->down = deep(t->type->down);
		nt->type->down->down = deep(t->type->down->down);
		break;

	case TSTRUCT:
		nt = shallow(t);
		nt->type = shallow(t->type);
		xt = nt->type;

		for(t=t->type; t!=T; t=t->down) {
			xt->type = deep(t->type);
			xt->down = shallow(t->down);
			xt = xt->down;
		}
		break;
	}
	return nt;
}

Node*
syslook(char *name, int copy)
{
	Sym *s;
	Node *n;

	s = pkglookup(name, runtimepkg);
	if(s == S || s->def == N)
		fatal("syslook: can't find runtime.%s", name);

	if(!copy)
		return s->def;

	n = nod(0, N, N);
	*n = *s->def;
	n->type = deep(s->def->type);

	return n;
}

/*
 * compute a hash value for type t.
 * if t is a method type, ignore the receiver
 * so that the hash can be used in interface checks.
 * %T already contains
 * all the necessary logic to generate a representation
 * of the type that completely describes it.
 * using smprint here avoids duplicating that code.
 * using md5 here is overkill, but i got tired of
 * accidental collisions making the runtime think
 * two types are equal when they really aren't.
 */
uint32
typehash(Type *t)
{
	char *p;
	MD5 d;

	if(t->thistuple) {
		// hide method receiver from Tpretty
		t->thistuple = 0;
		p = smprint("%-uT", t);
		t->thistuple = 1;
	} else
		p = smprint("%-uT", t);
	//print("typehash: %s\n", p);
	md5reset(&d);
	md5write(&d, (uchar*)p, strlen(p));
	free(p);
	return md5sum(&d);
}

Type*
ptrto(Type *t)
{
	Type *t1;

	if(tptr == 0)
		fatal("ptrto: no tptr");
	t1 = typ(tptr);
	t1->type = t;
	t1->width = widthptr;
	t1->align = widthptr;
	return t1;
}

void
frame(int context)
{
	char *p;
	NodeList *l;
	Node *n;
	int flag;

	p = "stack";
	l = nil;
	if(curfn)
		l = curfn->dcl;
	if(context) {
		p = "external";
		l = externdcl;
	}

	flag = 1;
	for(; l; l=l->next) {
		n = l->n;
		switch(n->op) {
		case ONAME:
			if(flag)
				print("--- %s frame ---\n", p);
			print("%O %S G%d %T\n", n->op, n->sym, n->vargen, n->type);
			flag = 0;
			break;

		case OTYPE:
			if(flag)
				print("--- %s frame ---\n", p);
			print("%O %T\n", n->op, n->type);
			flag = 0;
			break;
		}
	}
}

/*
 * calculate sethi/ullman number
 * roughly how many registers needed to
 * compile a node. used to compile the
 * hardest side first to minimize registers.
 */
void
ullmancalc(Node *n)
{
	int ul, ur;

	if(n == N)
		return;

	if(n->ninit != nil) {
		ul = UINF;
		goto out;
	}

	switch(n->op) {
	case OREGISTER:
	case OLITERAL:
	case ONAME:
		ul = 1;
		if(n->class == PPARAMREF || (n->class & PHEAP))
			ul++;
		goto out;
	case OCALL:
	case OCALLFUNC:
	case OCALLMETH:
	case OCALLINTER:
		ul = UINF;
		goto out;
	}
	ul = 1;
	if(n->left != N)
		ul = n->left->ullman;
	ur = 1;
	if(n->right != N)
		ur = n->right->ullman;
	if(ul == ur)
		ul += 1;
	if(ur > ul)
		ul = ur;

out:
	n->ullman = ul;
}

void
badtype(int o, Type *tl, Type *tr)
{
	Fmt fmt;
	char *s;
	
	fmtstrinit(&fmt);
	if(tl != T)
		fmtprint(&fmt, "\n	%T", tl);
	if(tr != T)
		fmtprint(&fmt, "\n	%T", tr);

	// common mistake: *struct and *interface.
	if(tl && tr && isptr[tl->etype] && isptr[tr->etype]) {
		if(tl->type->etype == TSTRUCT && tr->type->etype == TINTER)
			fmtprint(&fmt, "\n	(*struct vs *interface)");
		else if(tl->type->etype == TINTER && tr->type->etype == TSTRUCT)
			fmtprint(&fmt, "\n	(*interface vs *struct)");
	}
	s = fmtstrflush(&fmt);
	yyerror("illegal types for operand: %O%s", o, s);
}

/*
 * iterator to walk a structure declaration
 */
Type*
structfirst(Iter *s, Type **nn)
{
	Type *n, *t;

	n = *nn;
	if(n == T)
		goto bad;

	switch(n->etype) {
	default:
		goto bad;

	case TSTRUCT:
	case TINTER:
	case TFUNC:
		break;
	}

	t = n->type;
	if(t == T)
		goto rnil;

	if(t->etype != TFIELD)
		fatal("structfirst: not field %T", t);

	s->t = t;
	return t;

bad:
	fatal("structfirst: not struct %T", n);

rnil:
	return T;
}

Type*
structnext(Iter *s)
{
	Type *n, *t;

	n = s->t;
	t = n->down;
	if(t == T)
		goto rnil;

	if(t->etype != TFIELD)
		goto bad;

	s->t = t;
	return t;

bad:
	fatal("structnext: not struct %T", n);

rnil:
	return T;
}

/*
 * iterator to this and inargs in a function
 */
Type*
funcfirst(Iter *s, Type *t)
{
	Type *fp;

	if(t == T)
		goto bad;

	if(t->etype != TFUNC)
		goto bad;

	s->tfunc = t;
	s->done = 0;
	fp = structfirst(s, getthis(t));
	if(fp == T) {
		s->done = 1;
		fp = structfirst(s, getinarg(t));
	}
	return fp;

bad:
	fatal("funcfirst: not func %T", t);
	return T;
}

Type*
funcnext(Iter *s)
{
	Type *fp;

	fp = structnext(s);
	if(fp == T && !s->done) {
		s->done = 1;
		fp = structfirst(s, getinarg(s->tfunc));
	}
	return fp;
}

Type**
getthis(Type *t)
{
	if(t->etype != TFUNC)
		fatal("getthis: not a func %T", t);
	return &t->type;
}

Type**
getoutarg(Type *t)
{
	if(t->etype != TFUNC)
		fatal("getoutarg: not a func %T", t);
	return &t->type->down;
}

Type**
getinarg(Type *t)
{
	if(t->etype != TFUNC)
		fatal("getinarg: not a func %T", t);
	return &t->type->down->down;
}

Type*
getthisx(Type *t)
{
	return *getthis(t);
}

Type*
getoutargx(Type *t)
{
	return *getoutarg(t);
}

Type*
getinargx(Type *t)
{
	return *getinarg(t);
}

/*
 * return !(op)
 * eg == <=> !=
 */
int
brcom(int a)
{
	switch(a) {
	case OEQ:	return ONE;
	case ONE:	return OEQ;
	case OLT:	return OGE;
	case OGT:	return OLE;
	case OLE:	return OGT;
	case OGE:	return OLT;
	}
	fatal("brcom: no com for %A\n", a);
	return a;
}

/*
 * return reverse(op)
 * eg a op b <=> b r(op) a
 */
int
brrev(int a)
{
	switch(a) {
	case OEQ:	return OEQ;
	case ONE:	return ONE;
	case OLT:	return OGT;
	case OGT:	return OLT;
	case OLE:	return OGE;
	case OGE:	return OLE;
	}
	fatal("brcom: no rev for %A\n", a);
	return a;
}

/*
 * return side effect-free n, appending side effects to init.
 * result is assignable if n is.
 */
Node*
safeexpr(Node *n, NodeList **init)
{
	Node *l;
	Node *r;
	Node *a;

	if(n == N)
		return N;

	switch(n->op) {
	case ONAME:
	case OLITERAL:
		return n;

	case ODOT:
		l = safeexpr(n->left, init);
		if(l == n->left)
			return n;
		r = nod(OXXX, N, N);
		*r = *n;
		r->left = l;
		typecheck(&r, Erv);
		walkexpr(&r, init);
		return r;

	case ODOTPTR:
	case OIND:
		l = safeexpr(n->left, init);
		if(l == n->left)
			return n;
		a = nod(OXXX, N, N);
		*a = *n;
		a->left = l;
		walkexpr(&a, init);
		return a;

	case OINDEX:
	case OINDEXMAP:
		l = safeexpr(n->left, init);
		r = safeexpr(n->right, init);
		if(l == n->left && r == n->right)
			return n;
		a = nod(OXXX, N, N);
		*a = *n;
		a->left = l;
		a->right = r;
		walkexpr(&a, init);
		return a;
	}

	// make a copy; must not be used as an lvalue
	if(islvalue(n))
		fatal("missing lvalue case in safeexpr: %N", n);
	return cheapexpr(n, init);
}

Node*
copyexpr(Node *n, Type *t, NodeList **init)
{
	Node *a, *l;
	
	l = temp(t);
	a = nod(OAS, l, n);
	typecheck(&a, Etop);
	walkexpr(&a, init);
	*init = list(*init, a);
	return l;
}

/*
 * return side-effect free and cheap n, appending side effects to init.
 * result may not be assignable.
 */
Node*
cheapexpr(Node *n, NodeList **init)
{
	switch(n->op) {
	case ONAME:
	case OLITERAL:
		return n;
	}

	return copyexpr(n, n->type, init);
}

/*
 * return n in a local variable of type t if it is not already.
 */
Node*
localexpr(Node *n, Type *t, NodeList **init)
{
	if(n->op == ONAME &&
		(n->class == PAUTO || n->class == PPARAM || n->class == PPARAMOUT) &&
		convertop(n->type, t, nil) == OCONVNOP)
		return n;
	
	return copyexpr(n, t, init);
}

void
setmaxarg(Type *t)
{
	int32 w;

	dowidth(t);
	w = t->argwid;
	if(t->argwid >= MAXWIDTH)
		fatal("bad argwid %T", t);
	if(w > maxarg)
		maxarg = w;
}

/*
 * unicode-aware case-insensitive strcmp
 */

static int
ucistrcmp(char *p, char *q)
{
	Rune rp, rq;

	while(*p || *q) {
		if(*p == 0)
			return +1;
		if(*q == 0)
			return -1;
		p += chartorune(&rp, p);
		q += chartorune(&rq, q);
		rp = tolowerrune(rp);
		rq = tolowerrune(rq);
		if(rp < rq)
			return -1;
		if(rp > rq)
			return +1;
	}
	return 0;
}

/*
 * code to resolve elided DOTs
 * in embedded types
 */

// search depth 0 --
// return count of fields+methods
// found with a given name
static int
lookdot0(Sym *s, Type *t, Type **save, int ignorecase)
{
	Type *f, *u;
	int c;

	u = t;
	if(isptr[u->etype])
		u = u->type;

	c = 0;
	if(u->etype == TSTRUCT || u->etype == TINTER) {
		for(f=u->type; f!=T; f=f->down)
			if(f->sym == s || (ignorecase && ucistrcmp(f->sym->name, s->name) == 0)) {
				if(save)
					*save = f;
				c++;
			}
	}
	u = methtype(t);
	if(u != T) {
		for(f=u->method; f!=T; f=f->down)
			if(f->embedded == 0 && (f->sym == s || (ignorecase && ucistrcmp(f->sym->name, s->name) == 0))) {
				if(save)
					*save = f;
				c++;
			}
	}
	return c;
}

// search depth d for field/method s --
// return count of fields+methods
// found at search depth.
// answer is in dotlist array and
// count of number of ways is returned.
int
adddot1(Sym *s, Type *t, int d, Type **save, int ignorecase)
{
	Type *f, *u;
	int c, a;

	if(t->trecur)
		return 0;
	t->trecur = 1;

	if(d == 0) {
		c = lookdot0(s, t, save, ignorecase);
		goto out;
	}

	c = 0;
	u = t;
	if(isptr[u->etype])
		u = u->type;
	if(u->etype != TSTRUCT && u->etype != TINTER)
		goto out;

	d--;
	for(f=u->type; f!=T; f=f->down) {
		if(!f->embedded)
			continue;
		if(f->sym == S)
			continue;
		a = adddot1(s, f->type, d, save, ignorecase);
		if(a != 0 && c == 0)
			dotlist[d].field = f;
		c += a;
	}

out:
	t->trecur = 0;
	return c;
}

// in T.field
// find missing fields that
// will give shortest unique addressing.
// modify the tree with missing type names.
Node*
adddot(Node *n)
{
	Type *t;
	Sym *s;
	int c, d;

	typecheck(&n->left, Etype|Erv);
	t = n->left->type;
	if(t == T)
		goto ret;
	
	if(n->left->op == OTYPE)
		goto ret;

	if(n->right->op != ONAME)
		goto ret;
	s = n->right->sym;
	if(s == S)
		goto ret;

	for(d=0; d<nelem(dotlist); d++) {
		c = adddot1(s, t, d, nil, 0);
		if(c > 0)
			goto out;
	}
	goto ret;

out:
	if(c > 1) {
		yyerror("ambiguous selector %N", n);
		n->left = N;
		return n;
	}

	// rebuild elided dots
	for(c=d-1; c>=0; c--)
		n->left = nod(ODOT, n->left, newname(dotlist[c].field->sym));
ret:
	return n;
}


/*
 * code to help generate trampoline
 * functions for methods on embedded
 * subtypes.
 * these are approx the same as
 * the corresponding adddot routines
 * except that they expect to be called
 * with unique tasks and they return
 * the actual methods.
 */

typedef	struct	Symlink	Symlink;
struct	Symlink
{
	Type*		field;
	uchar		good;
	uchar		followptr;
	Symlink*	link;
};
static	Symlink*	slist;

static void
expand0(Type *t, int followptr)
{
	Type *f, *u;
	Symlink *sl;

	u = t;
	if(isptr[u->etype]) {
		followptr = 1;
		u = u->type;
	}

	if(u->etype == TINTER) {
		for(f=u->type; f!=T; f=f->down) {
			if(f->sym->flags & SymUniq)
				continue;
			f->sym->flags |= SymUniq;
			sl = mal(sizeof(*sl));
			sl->field = f;
			sl->link = slist;
			sl->followptr = followptr;
			slist = sl;
		}
		return;
	}

	u = methtype(t);
	if(u != T) {
		for(f=u->method; f!=T; f=f->down) {
			if(f->sym->flags & SymUniq)
				continue;
			f->sym->flags |= SymUniq;
			sl = mal(sizeof(*sl));
			sl->field = f;
			sl->link = slist;
			sl->followptr = followptr;
			slist = sl;
		}
	}
}

static void
expand1(Type *t, int d, int followptr)
{
	Type *f, *u;

	if(t->trecur)
		return;
	if(d == 0)
		return;
	t->trecur = 1;

	if(d != nelem(dotlist)-1)
		expand0(t, followptr);

	u = t;
	if(isptr[u->etype]) {
		followptr = 1;
		u = u->type;
	}
	if(u->etype != TSTRUCT && u->etype != TINTER)
		goto out;

	for(f=u->type; f!=T; f=f->down) {
		if(!f->embedded)
			continue;
		if(f->sym == S)
			continue;
		expand1(f->type, d-1, followptr);
	}

out:
	t->trecur = 0;
}

void
expandmeth(Sym *s, Type *t)
{
	Symlink *sl;
	Type *f;
	int c, d;

	if(s == S)
		return;
	if(t == T || t->xmethod != nil)
		return;

	// mark top-level method symbols
	// so that expand1 doesn't consider them.
	for(f=t->method; f != nil; f=f->down)
		f->sym->flags |= SymUniq;

	// generate all reachable methods
	slist = nil;
	expand1(t, nelem(dotlist)-1, 0);

	// check each method to be uniquely reachable
	for(sl=slist; sl!=nil; sl=sl->link) {
		sl->field->sym->flags &= ~SymUniq;
		for(d=0; d<nelem(dotlist); d++) {
			c = adddot1(sl->field->sym, t, d, &f, 0);
			if(c == 0)
				continue;
			if(c == 1) {
				// addot1 may have dug out arbitrary fields, we only want methods.
				if(f->type->etype == TFUNC && f->type->thistuple > 0) {
					sl->good = 1;
					sl->field = f;
				}
			}
			break;
		}
	}

	for(f=t->method; f != nil; f=f->down)
		f->sym->flags &= ~SymUniq;

	t->xmethod = t->method;
	for(sl=slist; sl!=nil; sl=sl->link) {
		if(sl->good) {
			// add it to the base type method list
			f = typ(TFIELD);
			*f = *sl->field;
			f->embedded = 1;	// needs a trampoline
			if(sl->followptr)
				f->embedded = 2;
			f->down = t->xmethod;
			t->xmethod = f;
		}
	}
}

/*
 * Given funarg struct list, return list of ODCLFIELD Node fn args.
 */
static NodeList*
structargs(Type **tl, int mustname)
{
	Iter savet;
	Node *a, *n;
	NodeList *args;
	Type *t;
	char buf[100];
	int gen;

	args = nil;
	gen = 0;
	for(t = structfirst(&savet, tl); t != T; t = structnext(&savet)) {
		n = N;
		if(mustname && (t->sym == nil || strcmp(t->sym->name, "_") == 0)) {
			// invent a name so that we can refer to it in the trampoline
			snprint(buf, sizeof buf, ".anon%d", gen++);
			n = newname(lookup(buf));
		} else if(t->sym)
			n = newname(t->sym);
		a = nod(ODCLFIELD, n, typenod(t->type));
		a->isddd = t->isddd;
		if(n != N)
			n->isddd = t->isddd;
		args = list(args, a);
	}
	return args;
}

/*
 * Generate a wrapper function to convert from
 * a receiver of type T to a receiver of type U.
 * That is,
 *
 *	func (t T) M() {
 *		...
 *	}
 *
 * already exists; this function generates
 *
 *	func (u U) M() {
 *		u.M()
 *	}
 *
 * where the types T and U are such that u.M() is valid
 * and calls the T.M method.
 * The resulting function is for use in method tables.
 *
 *	rcvr - U
 *	method - M func (t T)(), a TFIELD type struct
 *	newnam - the eventual mangled name of this function
 */
void
genwrapper(Type *rcvr, Type *method, Sym *newnam, int iface)
{
	Node *this, *fn, *call, *n, *t, *pad;
	NodeList *l, *args, *in, *out;
	Type *tpad;
	int isddd;
	Val v;

	if(debug['r'])
		print("genwrapper rcvrtype=%T method=%T newnam=%S\n",
			rcvr, method, newnam);

	lineno = 1;	// less confusing than end of input

	dclcontext = PEXTERN;
	markdcl();

	this = nod(ODCLFIELD, newname(lookup(".this")), typenod(rcvr));
	this->left->ntype = this->right;
	in = structargs(getinarg(method->type), 1);
	out = structargs(getoutarg(method->type), 0);

	t = nod(OTFUNC, N, N);
	l = list1(this);
	if(iface && rcvr->width < types[tptr]->width) {
		// Building method for interface table and receiver
		// is smaller than the single pointer-sized word
		// that the interface call will pass in.
		// Add a dummy padding argument after the
		// receiver to make up the difference.
		tpad = typ(TARRAY);
		tpad->type = types[TUINT8];
		tpad->bound = types[tptr]->width - rcvr->width;
		pad = nod(ODCLFIELD, newname(lookup(".pad")), typenod(tpad));
		l = list(l, pad);
	}
	t->list = concat(l, in);
	t->rlist = out;

	fn = nod(ODCLFUNC, N, N);
	fn->nname = newname(newnam);
	fn->nname->defn = fn;
	fn->nname->ntype = t;
	declare(fn->nname, PFUNC);
	funchdr(fn);

	// arg list
	args = nil;
	isddd = 0;
	for(l=in; l; l=l->next) {
		args = list(args, l->n->left);
		isddd = l->n->left->isddd;
	}
	
	// generate nil pointer check for better error
	if(isptr[rcvr->etype] && rcvr->type == getthisx(method->type)->type->type) {
		// generating wrapper from *T to T.
		n = nod(OIF, N, N);
		n->ntest = nod(OEQ, this->left, nodnil());
		// these strings are already in the reflect tables,
		// so no space cost to use them here.
		l = nil;
		v.ctype = CTSTR;
		v.u.sval = strlit(rcvr->type->sym->pkg->name);  // package name
		l = list(l, nodlit(v));
		v.u.sval = strlit(rcvr->type->sym->name);  // type name
		l = list(l, nodlit(v));
		v.u.sval = strlit(method->sym->name);
		l = list(l, nodlit(v));  // method name
		call = nod(OCALL, syslook("panicwrap", 0), N);
		call->list = l;
		n->nbody = list1(call);
		fn->nbody = list(fn->nbody, n);
	}

	// generate call
	call = nod(OCALL, adddot(nod(OXDOT, this->left, newname(method->sym))), N);
	call->list = args;
	call->isddd = isddd;
	if(method->type->outtuple > 0) {
		n = nod(ORETURN, N, N);
		n->list = list1(call);
		call = n;
	}
	fn->nbody = list(fn->nbody, call);

	if(0 && debug['r'])
		dumplist("genwrapper body", fn->nbody);

	funcbody(fn);
	curfn = fn;
	typecheck(&fn, Etop);
	typechecklist(fn->nbody, Etop);
	curfn = nil;
	funccompile(fn, 0);
}

static Node*
hashmem(Type *t, vlong width)
{
	Node *tfn, *n;
	Sym *sym;
	
	sym = pkglookup("memhash", runtimepkg);

	n = newname(sym);
	n->class = PFUNC;
	tfn = nod(OTFUNC, N, N);
	tfn->list = list(tfn->list, nod(ODCLFIELD, N, typenod(ptrto(types[TUINTPTR]))));
	tfn->list = list(tfn->list, nod(ODCLFIELD, N, typenod(types[TUINTPTR])));
	tfn->list = list(tfn->list, nod(ODCLFIELD, N, typenod(ptrto(t))));
	typecheck(&tfn, Etype);
	n->type = tfn->type;
	return n;
}

static Node*
hashfor(Type *t)
{
	int a;
	Sym *sym;
	Node *tfn, *n;

	a = algtype1(t, nil);
	switch(a) {
	case AMEM:
		return hashmem(t, t->width);
	case AINTER:
		sym = pkglookup("interhash", runtimepkg);
		break;
	case ANILINTER:
		sym = pkglookup("nilinterhash", runtimepkg);
		break;
	case ASTRING:
		sym = pkglookup("strhash", runtimepkg);
		break;
	case AFLOAT32:
		sym = pkglookup("f32hash", runtimepkg);
		break;
	case AFLOAT64:
		sym = pkglookup("f64hash", runtimepkg);
		break;
	case ACPLX64:
		sym = pkglookup("c64hash", runtimepkg);
		break;
	case ACPLX128:
		sym = pkglookup("c128hash", runtimepkg);
		break;
	default:
		sym = typesymprefix(".hash", t);
		break;
	}

	n = newname(sym);
	n->class = PFUNC;
	tfn = nod(OTFUNC, N, N);
	tfn->list = list(tfn->list, nod(ODCLFIELD, N, typenod(ptrto(types[TUINTPTR]))));
	tfn->list = list(tfn->list, nod(ODCLFIELD, N, typenod(types[TUINTPTR])));
	tfn->list = list(tfn->list, nod(ODCLFIELD, N, typenod(ptrto(t))));
	typecheck(&tfn, Etype);
	n->type = tfn->type;
	return n;
}

/*
 * Generate a helper function to compute the hash of a value of type t.
 */
void
genhash(Sym *sym, Type *t)
{
	Node *n, *fn, *np, *nh, *ni, *call, *nx, *na, *tfn;
	Node *hashel;
	Type *first, *t1;
	int old_safemode;
	int64 size, mul;

	if(debug['r'])
		print("genhash %S %T\n", sym, t);

	lineno = 1;  // less confusing than end of input
	dclcontext = PEXTERN;
	markdcl();

	// func sym(h *uintptr, s uintptr, p *T)
	fn = nod(ODCLFUNC, N, N);
	fn->nname = newname(sym);
	fn->nname->class = PFUNC;
	tfn = nod(OTFUNC, N, N);
	fn->nname->ntype = tfn;

	n = nod(ODCLFIELD, newname(lookup("h")), typenod(ptrto(types[TUINTPTR])));
	tfn->list = list(tfn->list, n);
	nh = n->left;
	n = nod(ODCLFIELD, newname(lookup("s")), typenod(types[TUINTPTR]));
	tfn->list = list(tfn->list, n);
	n = nod(ODCLFIELD, newname(lookup("p")), typenod(ptrto(t)));
	tfn->list = list(tfn->list, n);
	np = n->left;

	funchdr(fn);
	typecheck(&fn->nname->ntype, Etype);

	// genhash is only called for types that have equality but
	// cannot be handled by the standard algorithms,
	// so t must be either an array or a struct.
	switch(t->etype) {
	default:
		fatal("genhash %T", t);
	case TARRAY:
		if(isslice(t))
			fatal("genhash %T", t);
		// An array of pure memory would be handled by the
		// standard algorithm, so the element type must not be
		// pure memory.
		hashel = hashfor(t->type);
		n = nod(ORANGE, N, nod(OIND, np, N));
		ni = newname(lookup("i"));
		ni->type = types[TINT];
		n->list = list1(ni);
		n->colas = 1;
		colasdefn(n->list, n);
		ni = n->list->n;

		// *h = *h<<3 | *h>>61
		n->nbody = list(n->nbody,
			nod(OAS,
				nod(OIND, nh, N),
				nod(OOR,
					nod(OLSH, nod(OIND, nh, N), nodintconst(3)),
					nod(ORSH, nod(OIND, nh, N), nodintconst(widthptr*8-3)))));

		// *h *= mul
		// Same multipliers as in runtime.memhash.
		if(widthptr == 4)
			mul = 3267000013LL;
		else
			mul = 23344194077549503LL;
		n->nbody = list(n->nbody,
			nod(OAS,
				nod(OIND, nh, N),
				nod(OMUL, nod(OIND, nh, N), nodintconst(mul))));

		// hashel(h, sizeof(p[i]), &p[i])
		call = nod(OCALL, hashel, N);
		call->list = list(call->list, nh);
		call->list = list(call->list, nodintconst(t->type->width));
		nx = nod(OINDEX, np, ni);
		nx->etype = 1;  // no bounds check
		na = nod(OADDR, nx, N);
		na->etype = 1;  // no escape to heap
		call->list = list(call->list, na);
		n->nbody = list(n->nbody, call);

		fn->nbody = list(fn->nbody, n);
		break;

	case TSTRUCT:
		// Walk the struct using memhash for runs of AMEM
		// and calling specific hash functions for the others.
		first = T;
		for(t1=t->type;; t1=t1->down) {
			if(t1 != T && algtype1(t1->type, nil) == AMEM) {
				if(first == T)
					first = t1;
				continue;
			}
			// Run memhash for fields up to this one.
			if(first != T) {
				if(first->down == t1)
					size = first->type->width;
				else if(t1 == T)
					size = t->width - first->width;  // first->width is offset
				else
					size = t1->width - first->width;  // both are offsets
				hashel = hashmem(first->type, size);
				// hashel(h, size, &p.first)
				call = nod(OCALL, hashel, N);
				call->list = list(call->list, nh);
				call->list = list(call->list, nodintconst(size));
				nx = nod(OXDOT, np, newname(first->sym));  // TODO: fields from other packages?
				na = nod(OADDR, nx, N);
				na->etype = 1;  // no escape to heap
				call->list = list(call->list, na);
				fn->nbody = list(fn->nbody, call);

				first = T;
			}
			if(t1 == T)
				break;

			// Run hash for this field.
			hashel = hashfor(t1->type);
			// hashel(h, size, &p.t1)
			call = nod(OCALL, hashel, N);
			call->list = list(call->list, nh);
			call->list = list(call->list, nodintconst(t1->type->width));
			nx = nod(OXDOT, np, newname(t1->sym));  // TODO: fields from other packages?
			na = nod(OADDR, nx, N);
			na->etype = 1;  // no escape to heap
			call->list = list(call->list, na);
			fn->nbody = list(fn->nbody, call);
		}
		break;
	}

	if(debug['r'])
		dumplist("genhash body", fn->nbody);

	funcbody(fn);
	curfn = fn;
	fn->dupok = 1;
	typecheck(&fn, Etop);
	typechecklist(fn->nbody, Etop);
	curfn = nil;

	// Disable safemode while compiling this code: the code we
	// generate internally can refer to unsafe.Pointer.
	// In this case it can happen if we need to generate an ==
	// for a struct containing a reflect.Value, which itself has
	// an unexported field of type unsafe.Pointer.
	old_safemode = safemode;
	safemode = 0;
	funccompile(fn, 0);
	safemode = old_safemode;
}

// Return node for
//	if p.field != q.field { *eq = false; return }
static Node*
eqfield(Node *p, Node *q, Node *field, Node *eq)
{
	Node *nif, *nx, *ny;

	nx = nod(OXDOT, p, field);
	ny = nod(OXDOT, q, field);
	nif = nod(OIF, N, N);
	nif->ntest = nod(ONE, nx, ny);
	nif->nbody = list(nif->nbody, nod(OAS, nod(OIND, eq, N), nodbool(0)));
	nif->nbody = list(nif->nbody, nod(ORETURN, N, N));
	return nif;
}

static Node*
eqmemfunc(vlong size, Type *type)
{
	char buf[30];
	Node *fn;

	switch(size) {
	default:
		fn = syslook("memequal", 1);
		break;
	case 1:
	case 2:
	case 4:
	case 8:
	case 16:
		snprint(buf, sizeof buf, "memequal%d", (int)size*8);
		fn = syslook(buf, 1);
		break;
	}
	argtype(fn, type);
	argtype(fn, type);
	return fn;
}

// Return node for
//	if memequal(size, &p.field, &q.field, eq); !*eq { return }
static Node*
eqmem(Node *p, Node *q, Node *field, vlong size, Node *eq)
{
	Node *nif, *nx, *ny, *call;

	nx = nod(OADDR, nod(OXDOT, p, field), N);
	nx->etype = 1;  // does not escape
	ny = nod(OADDR, nod(OXDOT, q, field), N);
	ny->etype = 1;  // does not escape
	typecheck(&nx, Erv);
	typecheck(&ny, Erv);

	call = nod(OCALL, eqmemfunc(size, nx->type->type), N);
	call->list = list(call->list, eq);
	call->list = list(call->list, nodintconst(size));
	call->list = list(call->list, nx);
	call->list = list(call->list, ny);

	nif = nod(OIF, N, N);
	nif->ninit = list(nif->ninit, call);
	nif->ntest = nod(ONOT, nod(OIND, eq, N), N);
	nif->nbody = list(nif->nbody, nod(ORETURN, N, N));
	return nif;
}

/*
 * Generate a helper function to check equality of two values of type t.
 */
void
geneq(Sym *sym, Type *t)
{
	Node *n, *fn, *np, *neq, *nq, *tfn, *nif, *ni, *nx, *ny, *nrange;
	Type *t1, *first;
	int old_safemode;
	int64 size;

	if(debug['r'])
		print("geneq %S %T\n", sym, t);

	lineno = 1;  // less confusing than end of input
	dclcontext = PEXTERN;
	markdcl();

	// func sym(eq *bool, s uintptr, p, q *T)
	fn = nod(ODCLFUNC, N, N);
	fn->nname = newname(sym);
	fn->nname->class = PFUNC;
	tfn = nod(OTFUNC, N, N);
	fn->nname->ntype = tfn;

	n = nod(ODCLFIELD, newname(lookup("eq")), typenod(ptrto(types[TBOOL])));
	tfn->list = list(tfn->list, n);
	neq = n->left;
	n = nod(ODCLFIELD, newname(lookup("s")), typenod(types[TUINTPTR]));
	tfn->list = list(tfn->list, n);
	n = nod(ODCLFIELD, newname(lookup("p")), typenod(ptrto(t)));
	tfn->list = list(tfn->list, n);
	np = n->left;
	n = nod(ODCLFIELD, newname(lookup("q")), typenod(ptrto(t)));
	tfn->list = list(tfn->list, n);
	nq = n->left;

	funchdr(fn);

	// geneq is only called for types that have equality but
	// cannot be handled by the standard algorithms,
	// so t must be either an array or a struct.
	switch(t->etype) {
	default:
		fatal("geneq %T", t);
	case TARRAY:
		if(isslice(t))
			fatal("geneq %T", t);
		// An array of pure memory would be handled by the
		// standard memequal, so the element type must not be
		// pure memory.  Even if we unrolled the range loop,
		// each iteration would be a function call, so don't bother
		// unrolling.
		nrange = nod(ORANGE, N, nod(OIND, np, N));
		ni = newname(lookup("i"));
		ni->type = types[TINT];
		nrange->list = list1(ni);
		nrange->colas = 1;
		colasdefn(nrange->list, nrange);
		ni = nrange->list->n;
		
		// if p[i] != q[i] { *eq = false; return }
		nx = nod(OINDEX, np, ni);
		nx->etype = 1;  // no bounds check
		ny = nod(OINDEX, nq, ni);
		ny->etype = 1;  // no bounds check

		nif = nod(OIF, N, N);
		nif->ntest = nod(ONE, nx, ny);
		nif->nbody = list(nif->nbody, nod(OAS, nod(OIND, neq, N), nodbool(0)));
		nif->nbody = list(nif->nbody, nod(ORETURN, N, N));
		nrange->nbody = list(nrange->nbody, nif);
		fn->nbody = list(fn->nbody, nrange);

		// *eq = true;
		fn->nbody = list(fn->nbody, nod(OAS, nod(OIND, neq, N), nodbool(1)));
		break;

	case TSTRUCT:
		// Walk the struct using memequal for runs of AMEM
		// and calling specific equality tests for the others.
		first = T;
		for(t1=t->type;; t1=t1->down) {
			if(t1 != T && algtype1(t1->type, nil) == AMEM) {
				if(first == T)
					first = t1;
				continue;
			}
			// Run memequal for fields up to this one.
			// TODO(rsc): All the calls to newname are wrong for
			// cross-package unexported fields.
			if(first != T) {
				if(first->down == t1) {
					fn->nbody = list(fn->nbody, eqfield(np, nq, newname(first->sym), neq));
				} else if(first->down->down == t1) {
					fn->nbody = list(fn->nbody, eqfield(np, nq, newname(first->sym), neq));
					first = first->down;
					fn->nbody = list(fn->nbody, eqfield(np, nq, newname(first->sym), neq));
				} else {
					// More than two fields: use memequal.
					if(t1 == T)
						size = t->width - first->width;  // first->width is offset
					else
						size = t1->width - first->width;  // both are offsets
					fn->nbody = list(fn->nbody, eqmem(np, nq, newname(first->sym), size, neq));
				}
				first = T;
			}
			if(t1 == T)
				break;

			// Check this field, which is not just memory.
			fn->nbody = list(fn->nbody, eqfield(np, nq, newname(t1->sym), neq));
		}

		// *eq = true;
		fn->nbody = list(fn->nbody, nod(OAS, nod(OIND, neq, N), nodbool(1)));
		break;
	}

	if(debug['r'])
		dumplist("geneq body", fn->nbody);

	funcbody(fn);
	curfn = fn;
	fn->dupok = 1;
	typecheck(&fn, Etop);
	typechecklist(fn->nbody, Etop);
	curfn = nil;
	
	// Disable safemode while compiling this code: the code we
	// generate internally can refer to unsafe.Pointer.
	// In this case it can happen if we need to generate an ==
	// for a struct containing a reflect.Value, which itself has
	// an unexported field of type unsafe.Pointer.
	old_safemode = safemode;
	safemode = 0;
	funccompile(fn, 0);
	safemode = old_safemode;
}

static Type*
ifacelookdot(Sym *s, Type *t, int *followptr, int ignorecase)
{
	int i, c, d;
	Type *m;

	*followptr = 0;

	if(t == T)
		return T;

	for(d=0; d<nelem(dotlist); d++) {
		c = adddot1(s, t, d, &m, ignorecase);
		if(c > 1) {
			yyerror("%T.%S is ambiguous", t, s);
			return T;
		}
		if(c == 1) {
			for(i=0; i<d; i++) {
				if(isptr[dotlist[i].field->type->etype]) {
					*followptr = 1;
					break;
				}
			}
			if(m->type->etype != TFUNC || m->type->thistuple == 0) {
				yyerror("%T.%S is a field, not a method", t, s);
				return T;
			}
			return m;
		}
	}
	return T;
}

int
implements(Type *t, Type *iface, Type **m, Type **samename, int *ptr)
{
	Type *t0, *im, *tm, *rcvr, *imtype;
	int followptr;

	t0 = t;
	if(t == T)
		return 0;

	// if this is too slow,
	// could sort these first
	// and then do one loop.

	if(t->etype == TINTER) {
		for(im=iface->type; im; im=im->down) {
			for(tm=t->type; tm; tm=tm->down) {
				if(tm->sym == im->sym) {
					if(eqtype(tm->type, im->type))
						goto found;
					*m = im;
					*samename = tm;
					*ptr = 0;
					return 0;
				}
			}
			*m = im;
			*samename = nil;
			*ptr = 0;
			return 0;
		found:;
		}
		return 1;
	}

	t = methtype(t);
	if(t != T)
		expandmeth(t->sym, t);
	for(im=iface->type; im; im=im->down) {
		imtype = methodfunc(im->type, 0);
		tm = ifacelookdot(im->sym, t, &followptr, 0);
		if(tm == T || !eqtype(methodfunc(tm->type, 0), imtype)) {
			if(tm == T)
				tm = ifacelookdot(im->sym, t, &followptr, 1);
			*m = im;
			*samename = tm;
			*ptr = 0;
			return 0;
		}
		// if pointer receiver in method,
		// the method does not exist for value types.
		rcvr = getthisx(tm->type)->type->type;
		if(isptr[rcvr->etype] && !isptr[t0->etype] && !followptr && !isifacemethod(tm->type)) {
			if(0 && debug['r'])
				yyerror("interface pointer mismatch");

			*m = im;
			*samename = nil;
			*ptr = 1;
			return 0;
		}
	}
	return 1;
}

/*
 * even simpler simtype; get rid of ptr, bool.
 * assuming that the front end has rejected
 * all the invalid conversions (like ptr -> bool)
 */
int
simsimtype(Type *t)
{
	int et;

	if(t == 0)
		return 0;

	et = simtype[t->etype];
	switch(et) {
	case TPTR32:
		et = TUINT32;
		break;
	case TPTR64:
		et = TUINT64;
		break;
	case TBOOL:
		et = TUINT8;
		break;
	}
	return et;
}

NodeList*
concat(NodeList *a, NodeList *b)
{
	if(a == nil)
		return b;
	if(b == nil)
		return a;

	a->end->next = b;
	a->end = b->end;
	b->end = nil;
	return a;
}

NodeList*
list1(Node *n)
{
	NodeList *l;

	if(n == nil)
		return nil;
	if(n->op == OBLOCK && n->ninit == nil) {
		// Flatten list and steal storage.
		// Poison pointer to catch errant uses.
		l = n->list;
		n->list = (NodeList*)1;
		return l;
	}
	l = mal(sizeof *l);
	l->n = n;
	l->end = l;
	return l;
}

NodeList*
list(NodeList *l, Node *n)
{
	return concat(l, list1(n));
}

void
listsort(NodeList** l, int(*f)(Node*, Node*))
{
	NodeList *l1, *l2, *le;

	if(*l == nil || (*l)->next == nil)
		return;

	l1 = *l;
	l2 = *l;
	for(;;) {
		l2 = l2->next;
		if(l2 == nil)
			break;
		l2 = l2->next;
		if(l2 == nil)
			break;
		l1 = l1->next;
	}

	l2 = l1->next;
	l1->next = nil;
	l2->end = (*l)->end;
	(*l)->end = l1;

	l1 = *l;
	listsort(&l1, f);
	listsort(&l2, f);

	if((*f)(l1->n, l2->n) < 0) {
		*l = l1;
	} else {
		*l = l2;
		l2 = l1;
		l1 = *l;
	}

	// now l1 == *l; and l1 < l2

	while ((l1 != nil) && (l2 != nil)) {
		while ((l1->next != nil) && (*f)(l1->next->n, l2->n) < 0)
			l1 = l1->next;
		
		// l1 is last one from l1 that is < l2
		le = l1->next;		// le is the rest of l1, first one that is >= l2
		if(le != nil)
			le->end = (*l)->end;

		(*l)->end = l1;		// cut *l at l1
		*l = concat(*l, l2);	// glue l2 to *l's tail

		l1 = l2;		// l1 is the first element of *l that is < the new l2
		l2 = le;		// ... because l2 now is the old tail of l1
	}

	*l = concat(*l, l2);		// any remainder 
}

NodeList*
listtreecopy(NodeList *l)
{
	NodeList *out;

	out = nil;
	for(; l; l=l->next)
		out = list(out, treecopy(l->n));
	return out;
}

Node*
liststmt(NodeList *l)
{
	Node *n;

	n = nod(OBLOCK, N, N);
	n->list = l;
	if(l)
		n->lineno = l->n->lineno;
	return n;
}

/*
 * return nelem of list
 */
int
count(NodeList *l)
{
	int n;

	n = 0;
	for(; l; l=l->next)
		n++;
	return n;
}

/*
 * return nelem of list
 */
int
structcount(Type *t)
{
	int v;
	Iter s;

	v = 0;
	for(t = structfirst(&s, &t); t != T; t = structnext(&s))
		v++;
	return v;
}

/*
 * return power of 2 of the constant
 * operand. -1 if it is not a power of 2.
 * 1000+ if it is a -(power of 2)
 */
int
powtwo(Node *n)
{
	uvlong v, b;
	int i;

	if(n == N || n->op != OLITERAL || n->type == T)
		goto no;
	if(!isint[n->type->etype])
		goto no;

	v = mpgetfix(n->val.u.xval);
	b = 1ULL;
	for(i=0; i<64; i++) {
		if(b == v)
			return i;
		b = b<<1;
	}

	if(!issigned[n->type->etype])
		goto no;

	v = -v;
	b = 1ULL;
	for(i=0; i<64; i++) {
		if(b == v)
			return i+1000;
		b = b<<1;
	}

no:
	return -1;
}

/*
 * return the unsigned type for
 * a signed integer type.
 * returns T if input is not a
 * signed integer type.
 */
Type*
tounsigned(Type *t)
{

	// this is types[et+1], but not sure
	// that this relation is immutable
	switch(t->etype) {
	default:
		print("tounsigned: unknown type %T\n", t);
		t = T;
		break;
	case TINT:
		t = types[TUINT];
		break;
	case TINT8:
		t = types[TUINT8];
		break;
	case TINT16:
		t = types[TUINT16];
		break;
	case TINT32:
		t = types[TUINT32];
		break;
	case TINT64:
		t = types[TUINT64];
		break;
	}
	return t;
}

/*
 * magic number for signed division
 * see hacker's delight chapter 10
 */
void
smagic(Magic *m)
{
	int p;
	uint64 ad, anc, delta, q1, r1, q2, r2, t;
	uint64 mask, two31;

	m->bad = 0;
	switch(m->w) {
	default:
		m->bad = 1;
		return;
	case 8:
		mask = 0xffLL;
		break;
	case 16:
		mask = 0xffffLL;
		break;
	case 32:
		mask = 0xffffffffLL;
		break;
	case 64:
		mask = 0xffffffffffffffffLL;
		break;
	}
	two31 = mask ^ (mask>>1);

	p = m->w-1;
	ad = m->sd;
	if(m->sd < 0)
		ad = -m->sd;

	// bad denominators
	if(ad == 0 || ad == 1 || ad == two31) {
		m->bad = 1;
		return;
	}

	t = two31;
	ad &= mask;

	anc = t - 1 - t%ad;
	anc &= mask;

	q1 = two31/anc;
	r1 = two31 - q1*anc;
	q1 &= mask;
	r1 &= mask;

	q2 = two31/ad;
	r2 = two31 - q2*ad;
	q2 &= mask;
	r2 &= mask;

	for(;;) {
		p++;
		q1 <<= 1;
		r1 <<= 1;
		q1 &= mask;
		r1 &= mask;
		if(r1 >= anc) {
			q1++;
			r1 -= anc;
			q1 &= mask;
			r1 &= mask;
		}

		q2 <<= 1;
		r2 <<= 1;
		q2 &= mask;
		r2 &= mask;
		if(r2 >= ad) {
			q2++;
			r2 -= ad;
			q2 &= mask;
			r2 &= mask;
		}

		delta = ad - r2;
		delta &= mask;
		if(q1 < delta || (q1 == delta && r1 == 0)) {
			continue;
		}
		break;
	}

	m->sm = q2+1;
	if(m->sm & two31)
		m->sm |= ~mask;
	m->s = p-m->w;
}

/*
 * magic number for unsigned division
 * see hacker's delight chapter 10
 */
void
umagic(Magic *m)
{
	int p;
	uint64 nc, delta, q1, r1, q2, r2;
	uint64 mask, two31;

	m->bad = 0;
	m->ua = 0;

	switch(m->w) {
	default:
		m->bad = 1;
		return;
	case 8:
		mask = 0xffLL;
		break;
	case 16:
		mask = 0xffffLL;
		break;
	case 32:
		mask = 0xffffffffLL;
		break;
	case 64:
		mask = 0xffffffffffffffffLL;
		break;
	}
	two31 = mask ^ (mask>>1);

	m->ud &= mask;
	if(m->ud == 0 || m->ud == two31) {
		m->bad = 1;
		return;
	}
	nc = mask - (-m->ud&mask)%m->ud;
	p = m->w-1;

	q1 = two31/nc;
	r1 = two31 - q1*nc;
	q1 &= mask;
	r1 &= mask;

	q2 = (two31-1) / m->ud;
	r2 = (two31-1) - q2*m->ud;
	q2 &= mask;
	r2 &= mask;

	for(;;) {
		p++;
		if(r1 >= nc-r1) {
			q1 <<= 1;
			q1++;
			r1 <<= 1;
			r1 -= nc;
		} else {
			q1 <<= 1;
			r1 <<= 1;
		}
		q1 &= mask;
		r1 &= mask;
		if(r2+1 >= m->ud-r2) {
			if(q2 >= two31-1) {
				m->ua = 1;
			}
			q2 <<= 1;
			q2++;
			r2 <<= 1;
			r2++;
			r2 -= m->ud;
		} else {
			if(q2 >= two31) {
				m->ua = 1;
			}
			q2 <<= 1;
			r2 <<= 1;
			r2++;
		}
		q2 &= mask;
		r2 &= mask;

		delta = m->ud - 1 - r2;
		delta &= mask;

		if(p < m->w+m->w)
		if(q1 < delta || (q1 == delta && r1 == 0)) {
			continue;
		}
		break;
	}
	m->um = q2+1;
	m->s = p-m->w;
}

Sym*
ngotype(Node *n)
{
	if(n->sym != S && n->realtype != T)
	if(strncmp(n->sym->name, "autotmp_", 8) != 0)
	if(strncmp(n->sym->name, "statictmp_", 8) != 0)
		return typename(n->realtype)->left->sym;

	return S;
}

/*
 * Convert raw string to the prefix that will be used in the symbol
 * table.  All control characters, space, '%' and '"', as well as
 * non-7-bit clean bytes turn into %xx.  The period needs escaping
 * only in the last segment of the path, and it makes for happier
 * users if we escape that as little as possible.
 *
 * If you edit this, edit ../ld/lib.c:/^pathtoprefix copy too.
 */
static char*
pathtoprefix(char *s)
{
	static char hex[] = "0123456789abcdef";
	char *p, *r, *w, *l;
	int n;

	// find first character past the last slash, if any.
	l = s;
	for(r=s; *r; r++)
		if(*r == '/')
			l = r+1;

	// check for chars that need escaping
	n = 0;
	for(r=s; *r; r++)
		if(*r <= ' ' || (*r == '.' && r >= l) || *r == '%' || *r == '"' || *r >= 0x7f)
			n++;

	// quick exit
	if(n == 0)
		return s;

	// escape
	p = mal((r-s)+1+2*n);
	for(r=s, w=p; *r; r++) {
		if(*r <= ' ' || (*r == '.' && r >= l) || *r == '%' || *r == '"' || *r >= 0x7f) {
			*w++ = '%';
			*w++ = hex[(*r>>4)&0xF];
			*w++ = hex[*r&0xF];
		} else
			*w++ = *r;
	}
	*w = '\0';
	return p;
}

Pkg*
mkpkg(Strlit *path)
{
	Pkg *p;
	int h;
	
	if(strlen(path->s) != path->len) {
		yyerror("import path contains NUL byte");
		errorexit();
	}
	
	h = stringhash(path->s) & (nelem(phash)-1);
	for(p=phash[h]; p; p=p->link)
		if(p->path->len == path->len && memcmp(path->s, p->path->s, path->len) == 0)
			return p;

	p = mal(sizeof *p);
	p->path = path;
	p->prefix = pathtoprefix(path->s);
	p->link = phash[h];
	phash[h] = p;
	return p;
}

Strlit*
strlit(char *s)
{
	Strlit *t;
	
	t = mal(sizeof *t + strlen(s));
	strcpy(t->s, s);
	t->len = strlen(s);
	return t;
}

void
addinit(Node **np, NodeList *init)
{
	Node *n;
	
	if(init == nil)
		return;

	n = *np;
	switch(n->op) {
	case ONAME:
	case OLITERAL:
		// There may be multiple refs to this node;
		// introduce OCONVNOP to hold init list.
		n = nod(OCONVNOP, n, N);
		n->type = n->left->type;
		n->typecheck = 1;
		*np = n;
		break;
	}
	n->ninit = concat(init, n->ninit);
	n->ullman = UINF;
}
