// 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
algtype(Type *t)
{
	int a;

	if(issimple[t->etype] || isptr[t->etype] ||
		t->etype == TCHAN || t->etype == TFUNC || t->etype == TMAP) {
		if(t->width == 1)
			a = AMEM8;
		else if(t->width == 2)
			a = AMEM16;
		else if(t->width == 4)
			a = AMEM32;
		else if(t->width == 8)
			a = AMEM64;
		else if(t->width == 16)
			a = AMEM128;
		else
			a = AMEM;	// just bytes (int, ptr, etc)
	} else if(t->etype == TSTRING)
		a = ASTRING;	// string
	else if(isnilinter(t))
		a = ANILINTER;	// nil interface
	else if(t->etype == TINTER)
		a = AINTER;	// interface
	else if(isslice(t))
		a = ASLICE;	// slice
	else {
		if(t->width == 1)
			a = ANOEQ8;
		else if(t->width == 2)
			a = ANOEQ16;
		else if(t->width == 4)
			a = ANOEQ32;
		else if(t->width == 8)
			a = ANOEQ64;
		else if(t->width == 16)
			a = ANOEQ128;
		else
			a = ANOEQ;	// just bytes, but no hash/eq
	}
	return a;
}

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

	if(key != nil) {
		switch(key->etype) {
		case TARRAY:
		case TSTRUCT:
		case TMAP:
		case TFUNC:
			yyerror("invalid map key type %T", key);
			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:
			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;
}

// 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)
{
	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;
	}

	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 || !eqtype(t1->type, t2->type) || !eqnote(t1->note, t2->note))
				return 0;
		}
		return t1 == T && t2 == T;

	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 || !eqtype(ta->type, tb->type))
					return 0;
			}
			if(ta != T || tb != T)
				return 0;
		}
		return t1 == T && t2 == T;
	
	case TARRAY:
		if(t1->bound != t2->bound)
			return 0;
		break;
	
	case TCHAN:
		if(t1->chan != t2->chan)
			return 0;
		break;
	}

	return eqtype(t1->down, t2->down) && eqtype(t1->type, t2->type);
}

// 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 = "";

	if(safemode && 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) && src->sym == nil && dst->etype == TSTRING) {
		if(eqtype(src->type, bytetype))
			return OARRAYBYTESTR;
		if(eqtype(src->type, runetype))
			return OARRAYRUNESTR;
	}
	
	// 7. src is a string and dst is []byte or []rune.
	// String to slice.
	if(src->etype == TSTRING && isslice(dst) && dst->sym == nil) {
		if(eqtype(dst->type, bytetype))
			return OSTRARRAYBYTE;
		if(eqtype(dst->type, runetype))
			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;

	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);
}

static 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 --
// 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 DOT reference %T.%S", t, s);

	// 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(!exportname(f->sym->name) && f->sym->pkg != localpkg)
				continue;
			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(!exportname(f->sym->name) && f->sym->pkg != localpkg)
				continue;
			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(t->sym)
			n = newname(t->sym);
		else if(mustname) {
			// have to give it a name so we can refer to it in trampoline
			snprint(buf, sizeof buf, ".anon%d", gen++);
			n = newname(lookup(buf));
		}
		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(0 && 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);

	fn = nod(ODCLFUNC, N, N);
	fn->nname = newname(newnam);
	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->nname->ntype = t;
	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 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;
}
