The Go Programming Language

Text file src/cmd/gc/dcl.c

     1	// Copyright 2009 The Go Authors. All rights reserved.
     2	// Use of this source code is governed by a BSD-style
     3	// license that can be found in the LICENSE file.
     4	
     5	#include	"go.h"
     6	#include	"y.tab.h"
     7	
     8	static	void	funcargs(Node*);
     9	
    10	static int
    11	dflag(void)
    12	{
    13		if(!debug['d'])
    14			return 0;
    15		if(debug['y'])
    16			return 1;
    17		if(incannedimport)
    18			return 0;
    19		return 1;
    20	}
    21	
    22	/*
    23	 * declaration stack & operations
    24	 */
    25	
    26	static void
    27	dcopy(Sym *a, Sym *b)
    28	{
    29		a->pkg = b->pkg;
    30		a->name = b->name;
    31		a->def = b->def;
    32		a->block = b->block;
    33		a->lastlineno = b->lastlineno;
    34	}
    35	
    36	static Sym*
    37	push(void)
    38	{
    39		Sym *d;
    40	
    41		d = mal(sizeof(*d));
    42		d->lastlineno = lineno;
    43		d->link = dclstack;
    44		dclstack = d;
    45		return d;
    46	}
    47	
    48	static Sym*
    49	pushdcl(Sym *s)
    50	{
    51		Sym *d;
    52	
    53		d = push();
    54		dcopy(d, s);
    55		if(dflag())
    56			print("\t%L push %S %p\n", lineno, s, s->def);
    57		return d;
    58	}
    59	
    60	void
    61	popdcl(void)
    62	{
    63		Sym *d, *s;
    64		int lno;
    65	
    66	//	if(dflag())
    67	//		print("revert\n");
    68	
    69		for(d=dclstack; d!=S; d=d->link) {
    70			if(d->name == nil)
    71				break;
    72			s = pkglookup(d->name, d->pkg);
    73			lno = s->lastlineno;
    74			dcopy(s, d);
    75			d->lastlineno = lno;
    76			if(dflag())
    77				print("\t%L pop %S %p\n", lineno, s, s->def);
    78		}
    79		if(d == S)
    80			fatal("popdcl: no mark");
    81		dclstack = d->link;
    82		block = d->block;
    83	}
    84	
    85	void
    86	poptodcl(void)
    87	{
    88		// pop the old marker and push a new one
    89		// (cannot reuse the existing one)
    90		// because we use the markers to identify blocks
    91		// for the goto restriction checks.
    92		popdcl();
    93		markdcl();
    94	}
    95	
    96	void
    97	markdcl(void)
    98	{
    99		Sym *d;
   100	
   101		d = push();
   102		d->name = nil;		// used as a mark in fifo
   103		d->block = block;
   104	
   105		blockgen++;
   106		block = blockgen;
   107	
   108	//	if(dflag())
   109	//		print("markdcl\n");
   110	}
   111	
   112	void
   113	dumpdcl(char *st)
   114	{
   115		Sym *s, *d;
   116		int i;
   117	
   118		i = 0;
   119		for(d=dclstack; d!=S; d=d->link) {
   120			i++;
   121			print("    %.2d %p", i, d);
   122			if(d->name == nil) {
   123				print("\n");
   124				continue;
   125			}
   126			print(" '%s'", d->name);
   127			s = pkglookup(d->name, d->pkg);
   128			print(" %lS\n", s);
   129		}
   130	}
   131	
   132	void
   133	testdclstack(void)
   134	{
   135		Sym *d;
   136	
   137		for(d=dclstack; d!=S; d=d->link) {
   138			if(d->name == nil) {
   139				yyerror("mark left on the stack");
   140				continue;
   141			}
   142		}
   143	}
   144	
   145	void
   146	redeclare(Sym *s, char *where)
   147	{
   148		if(s->lastlineno == 0)
   149			yyerror("%S redeclared %s\n"
   150				"\tprevious declaration during import",
   151				s, where);
   152		else
   153			yyerror("%S redeclared %s\n"
   154				"\tprevious declaration at %L",
   155				s, where, s->lastlineno);
   156	}
   157	
   158	/*
   159	 * declare individual names - var, typ, const
   160	 */
   161	void
   162	declare(Node *n, int ctxt)
   163	{
   164		Sym *s;
   165		int gen;
   166		static int typegen, vargen;
   167	
   168		if(isblank(n))
   169			return;
   170	
   171		n->lineno = parserline();
   172		s = n->sym;
   173		gen = 0;
   174		if(ctxt == PEXTERN) {
   175			externdcl = list(externdcl, n);
   176			if(dflag())
   177				print("\t%L global decl %S %p\n", lineno, s, n);
   178		} else {
   179			if(curfn == nil && ctxt == PAUTO)
   180				fatal("automatic outside function");
   181			if(curfn != nil)
   182				curfn->dcl = list(curfn->dcl, n);
   183			if(n->op == OTYPE)
   184				gen = ++typegen;
   185			else if(n->op == ONAME)
   186				gen = ++vargen;
   187			pushdcl(s);
   188			n->curfn = curfn;
   189		}
   190		if(ctxt == PAUTO)
   191			n->xoffset = BADWIDTH;
   192	
   193		if(s->block == block)
   194			redeclare(s, "in this block");
   195	
   196		s->block = block;
   197		s->lastlineno = parserline();
   198		s->def = n;
   199		n->vargen = gen;
   200		n->funcdepth = funcdepth;
   201		n->class = ctxt;
   202	
   203		autoexport(n, ctxt);
   204	}
   205	
   206	void
   207	addvar(Node *n, Type *t, int ctxt)
   208	{
   209		if(n==N || n->sym == S || (n->op != ONAME && n->op != ONONAME) || t == T)
   210			fatal("addvar: n=%N t=%T nil", n, t);
   211	
   212		n->op = ONAME;
   213		declare(n, ctxt);
   214		n->type = t;
   215	}
   216	
   217	/*
   218	 * declare variables from grammar
   219	 * new_name_list (type | [type] = expr_list)
   220	 */
   221	NodeList*
   222	variter(NodeList *vl, Node *t, NodeList *el)
   223	{
   224		int doexpr;
   225		Node *v, *e, *as2;
   226		NodeList *init;
   227	
   228		init = nil;
   229		doexpr = el != nil;
   230		
   231		if(count(el) == 1 && count(vl) > 1) {
   232			e = el->n;
   233			as2 = nod(OAS2, N, N);
   234			as2->list = vl;
   235			as2->rlist = list1(e);
   236			for(; vl; vl=vl->next) {
   237				v = vl->n;
   238				v->op = ONAME;
   239				declare(v, dclcontext);
   240				v->ntype = t;
   241				v->defn = as2;
   242				if(funcdepth > 0)
   243					init = list(init, nod(ODCL, v, N));
   244			}
   245			return list(init, as2);
   246		}
   247		
   248		for(; vl; vl=vl->next) {
   249			if(doexpr) {
   250				if(el == nil) {
   251					yyerror("missing expr in var dcl");
   252					break;
   253				}
   254				e = el->n;
   255				el = el->next;
   256			} else
   257				e = N;
   258	
   259			v = vl->n;
   260			v->op = ONAME;
   261			declare(v, dclcontext);
   262			v->ntype = t;
   263	
   264			if(e != N || funcdepth > 0 || isblank(v)) {
   265				if(funcdepth > 0)
   266					init = list(init, nod(ODCL, v, N));
   267				e = nod(OAS, v, e);
   268				init = list(init, e);
   269				if(e->right != N)
   270					v->defn = e;
   271			}
   272		}
   273		if(el != nil)
   274			yyerror("extra expr in var dcl");
   275		return init;
   276	}
   277	
   278	/*
   279	 * declare constants from grammar
   280	 * new_name_list [[type] = expr_list]
   281	 */
   282	NodeList*
   283	constiter(NodeList *vl, Node *t, NodeList *cl)
   284	{
   285		Node *v, *c;
   286		NodeList *vv;
   287	
   288		vv = nil;
   289		if(cl == nil) {
   290			if(t != N)
   291				yyerror("constdcl cannot have type without expr");
   292			cl = lastconst;
   293			t = lasttype;
   294		} else {
   295			lastconst = cl;
   296			lasttype = t;
   297		}
   298		cl = listtreecopy(cl);
   299	
   300		for(; vl; vl=vl->next) {
   301			if(cl == nil) {
   302				yyerror("missing expr in const dcl");
   303				break;
   304			}
   305			c = cl->n;
   306			cl = cl->next;
   307	
   308			v = vl->n;
   309			v->op = OLITERAL;
   310			declare(v, dclcontext);
   311	
   312			v->ntype = t;
   313			v->defn = c;
   314	
   315			vv = list(vv, nod(ODCLCONST, v, N));
   316		}
   317		if(cl != nil)
   318			yyerror("extra expr in const dcl");
   319		iota += 1;
   320		return vv;
   321	}
   322	
   323	/*
   324	 * this generates a new name node,
   325	 * typically for labels or other one-off names.
   326	 */
   327	Node*
   328	newname(Sym *s)
   329	{
   330		Node *n;
   331	
   332		if(s == S)
   333			fatal("newname nil");
   334	
   335		n = nod(ONAME, N, N);
   336		n->sym = s;
   337		n->type = T;
   338		n->addable = 1;
   339		n->ullman = 1;
   340		n->xoffset = 0;
   341		return n;
   342	}
   343	
   344	/*
   345	 * this generates a new name node for a name
   346	 * being declared.
   347	 */
   348	Node*
   349	dclname(Sym *s)
   350	{
   351		Node *n;
   352	
   353		n = newname(s);
   354		n->op = ONONAME;	// caller will correct it
   355		return n;
   356	}
   357	
   358	Node*
   359	typenod(Type *t)
   360	{
   361		// if we copied another type with *t = *u
   362		// then t->nod might be out of date, so
   363		// check t->nod->type too
   364		if(t->nod == N || t->nod->type != t) {
   365			t->nod = nod(OTYPE, N, N);
   366			t->nod->type = t;
   367			t->nod->sym = t->sym;
   368		}
   369		return t->nod;
   370	}
   371	
   372	
   373	/*
   374	 * this will return an old name
   375	 * that has already been pushed on the
   376	 * declaration list. a diagnostic is
   377	 * generated if no name has been defined.
   378	 */
   379	Node*
   380	oldname(Sym *s)
   381	{
   382		Node *n;
   383		Node *c;
   384	
   385		n = s->def;
   386		if(n == N) {
   387			// maybe a top-level name will come along
   388			// to give this a definition later.
   389			// walkdef will check s->def again once
   390			// all the input source has been processed.
   391			n = newname(s);
   392			n->op = ONONAME;
   393			n->iota = iota;	// save current iota value in const declarations
   394		}
   395		if(curfn != nil && n->funcdepth > 0 && n->funcdepth != funcdepth && n->op == ONAME) {
   396			// inner func is referring to var in outer func.
   397			//
   398			// TODO(rsc): If there is an outer variable x and we
   399			// are parsing x := 5 inside the closure, until we get to
   400			// the := it looks like a reference to the outer x so we'll
   401			// make x a closure variable unnecessarily.
   402			if(n->closure == N || n->closure->funcdepth != funcdepth) {
   403				// create new closure var.
   404				c = nod(ONAME, N, N);
   405				c->sym = s;
   406				c->class = PPARAMREF;
   407				c->isddd = n->isddd;
   408				c->defn = n;
   409				c->addable = 0;
   410				c->ullman = 2;
   411				c->funcdepth = funcdepth;
   412				c->outer = n->closure;
   413				n->closure = c;
   414				c->closure = n;
   415				c->xoffset = 0;
   416				curfn->cvars = list(curfn->cvars, c);
   417			}
   418			// return ref to closure var, not original
   419			return n->closure;
   420		}
   421		return n;
   422	}
   423	
   424	/*
   425	 * same for types
   426	 */
   427	Type*
   428	newtype(Sym *s)
   429	{
   430		Type *t;
   431	
   432		t = typ(TFORW);
   433		t->sym = s;
   434		t->type = T;
   435		return t;
   436	}
   437	
   438	
   439	/*
   440	 * := declarations
   441	 */
   442	
   443	static int
   444	colasname(Node *n)
   445	{
   446		switch(n->op) {
   447		case ONAME:
   448		case ONONAME:
   449		case OPACK:
   450		case OTYPE:
   451		case OLITERAL:
   452			return n->sym != S;
   453		}
   454		return 0;
   455	}
   456	
   457	void
   458	colasdefn(NodeList *left, Node *defn)
   459	{
   460		int nnew, nerr;
   461		NodeList *l;
   462		Node *n;
   463	
   464		nnew = 0;
   465		nerr = 0;
   466		for(l=left; l; l=l->next) {
   467			n = l->n;
   468			if(isblank(n))
   469				continue;
   470			if(!colasname(n)) {
   471				yyerror("non-name %#N on left side of :=", n);
   472				nerr++;
   473				continue;
   474			}
   475			if(n->sym->block == block)
   476				continue;
   477	
   478			nnew++;
   479			n = newname(n->sym);
   480			declare(n, dclcontext);
   481			n->defn = defn;
   482			defn->ninit = list(defn->ninit, nod(ODCL, n, N));
   483			l->n = n;
   484		}
   485		if(nnew == 0 && nerr == 0)
   486			yyerror("no new variables on left side of :=");
   487	}
   488	
   489	Node*
   490	colas(NodeList *left, NodeList *right)
   491	{
   492		Node *as;
   493	
   494		as = nod(OAS2, N, N);
   495		as->list = left;
   496		as->rlist = right;
   497		as->colas = 1;
   498		colasdefn(left, as);
   499	
   500		// make the tree prettier; not necessary
   501		if(count(left) == 1 && count(right) == 1) {
   502			as->left = as->list->n;
   503			as->right = as->rlist->n;
   504			as->list = nil;
   505			as->rlist = nil;
   506			as->op = OAS;
   507		}
   508	
   509		return as;
   510	}
   511	
   512	/*
   513	 * declare the arguments in an
   514	 * interface field declaration.
   515	 */
   516	void
   517	ifacedcl(Node *n)
   518	{
   519		if(n->op != ODCLFIELD || n->right == N)
   520			fatal("ifacedcl");
   521	
   522		dclcontext = PAUTO;
   523		markdcl();
   524		funcdepth++;
   525		n->outer = curfn;
   526		curfn = n;
   527		funcargs(n->right);
   528	
   529		// funcbody is normally called after the parser has
   530		// seen the body of a function but since an interface
   531		// field declaration does not have a body, we must
   532		// call it now to pop the current declaration context.
   533		funcbody(n);
   534	}
   535	
   536	/*
   537	 * declare the function proper
   538	 * and declare the arguments.
   539	 * called in extern-declaration context
   540	 * returns in auto-declaration context.
   541	 */
   542	void
   543	funchdr(Node *n)
   544	{
   545	
   546		if(n->nname != N) {
   547			n->nname->op = ONAME;
   548			declare(n->nname, PFUNC);
   549			n->nname->defn = n;
   550		}
   551	
   552		// change the declaration context from extern to auto
   553		if(funcdepth == 0 && dclcontext != PEXTERN)
   554			fatal("funchdr: dclcontext");
   555	
   556		dclcontext = PAUTO;
   557		markdcl();
   558		funcdepth++;
   559	
   560		n->outer = curfn;
   561		curfn = n;
   562		if(n->nname)
   563			funcargs(n->nname->ntype);
   564		else
   565			funcargs(n->ntype);
   566	}
   567	
   568	static void
   569	funcargs(Node *nt)
   570	{
   571		Node *n;
   572		NodeList *l;
   573		int gen;
   574	
   575		if(nt->op != OTFUNC)
   576			fatal("funcargs %O", nt->op);
   577	
   578		// declare the receiver and in arguments.
   579		// no n->defn because type checking of func header
   580		// will fill in the types before we can demand them.
   581		if(nt->left != N) {
   582			n = nt->left;
   583			if(n->op != ODCLFIELD)
   584				fatal("funcargs1 %O", n->op);
   585			if(n->left != N) {
   586				n->left->op = ONAME;
   587				n->left->ntype = n->right;
   588				declare(n->left, PPARAM);
   589			}
   590		}
   591		for(l=nt->list; l; l=l->next) {
   592			n = l->n;
   593			if(n->op != ODCLFIELD)
   594				fatal("funcargs2 %O", n->op);
   595			if(n->left != N) {
   596				n->left->op = ONAME;
   597				n->left->ntype = n->right;
   598				declare(n->left, PPARAM);
   599			}
   600		}
   601	
   602		// declare the out arguments.
   603		gen = 0;
   604		for(l=nt->rlist; l; l=l->next) {
   605			n = l->n;
   606			if(n->op != ODCLFIELD)
   607				fatal("funcargs3 %O", n->op);
   608			if(n->left != N) {
   609				n->left->op = ONAME;
   610				n->left->ntype = n->right;
   611				if(isblank(n->left)) {
   612					// Give it a name so we can assign to it during return.
   613					snprint(namebuf, sizeof(namebuf), ".anon%d", gen++);
   614					n->left->sym = lookup(namebuf);
   615				}
   616				declare(n->left, PPARAMOUT);
   617			}
   618		}
   619	}
   620	
   621	/*
   622	 * finish the body.
   623	 * called in auto-declaration context.
   624	 * returns in extern-declaration context.
   625	 */
   626	void
   627	funcbody(Node *n)
   628	{
   629		// change the declaration context from auto to extern
   630		if(dclcontext != PAUTO)
   631			fatal("funcbody: dclcontext");
   632		popdcl();
   633		funcdepth--;
   634		curfn = n->outer;
   635		n->outer = N;
   636		if(funcdepth == 0)
   637			dclcontext = PEXTERN;
   638	}
   639	
   640	/*
   641	 * new type being defined with name s.
   642	 */
   643	Node*
   644	typedcl0(Sym *s)
   645	{
   646		Node *n;
   647	
   648		n = dclname(s);
   649		n->op = OTYPE;
   650		declare(n, dclcontext);
   651		return n;
   652	}
   653	
   654	/*
   655	 * node n, which was returned by typedcl0
   656	 * is being declared to have uncompiled type t.
   657	 * return the ODCLTYPE node to use.
   658	 */
   659	Node*
   660	typedcl1(Node *n, Node *t, int local)
   661	{
   662		n->ntype = t;
   663		n->local = local;
   664		return nod(ODCLTYPE, n, N);
   665	}
   666	
   667	/*
   668	 * typedcl1 but during imports
   669	 */
   670	void
   671	typedcl2(Type *pt, Type *t)
   672	{
   673		Node *n;
   674	
   675		// override declaration in unsafe.go for Pointer.
   676		// there is no way in Go code to define unsafe.Pointer
   677		// so we have to supply it.
   678		if(incannedimport &&
   679		   strcmp(importpkg->name, "unsafe") == 0 &&
   680		   strcmp(pt->nod->sym->name, "Pointer") == 0) {
   681			t = types[TUNSAFEPTR];
   682		}
   683	
   684		if(pt->etype == TFORW)
   685			goto ok;
   686		if(!eqtype(pt->orig, t))
   687			yyerror("inconsistent definition for type %S during import\n\t%lT\n\t%lT", pt->sym, pt->orig, t);
   688		return;
   689	
   690	ok:
   691		n = pt->nod;
   692		copytype(pt->nod, t);
   693		// unzero nod
   694		pt->nod = n;
   695	
   696		pt->sym->lastlineno = parserline();
   697		declare(n, PEXTERN);
   698	
   699		checkwidth(pt);
   700	}
   701	
   702	/*
   703	 * structs, functions, and methods.
   704	 * they don't belong here, but where do they belong?
   705	 */
   706	
   707	
   708	/*
   709	 * turn a parsed struct into a type
   710	 */
   711	static Type**
   712	stotype(NodeList *l, int et, Type **t, int funarg)
   713	{
   714		Type *f, *t1, *t2, **t0;
   715		Strlit *note;
   716		int lno;
   717		Node *n, *left;
   718		char *what;
   719	
   720		t0 = t;
   721		lno = lineno;
   722		what = "field";
   723		if(et == TINTER)
   724			what = "method";
   725	
   726		for(; l; l=l->next) {
   727			n = l->n;
   728			lineno = n->lineno;
   729			note = nil;
   730	
   731			if(n->op != ODCLFIELD)
   732				fatal("stotype: oops %N\n", n);
   733			left = n->left;
   734			if(funarg && isblank(left))
   735				left = N;
   736			if(n->right != N) {
   737				if(et == TINTER && left != N) {
   738					// queue resolution of method type for later.
   739					// right now all we need is the name list.
   740					// avoids cycles for recursive interface types.
   741					n->type = typ(TINTERMETH);
   742					n->type->nname = n->right;
   743					n->right = N;
   744					left->type = n->type;
   745					queuemethod(n);
   746				} else {
   747					typecheck(&n->right, Etype);
   748					n->type = n->right->type;
   749					if(n->type == T)
   750						continue;
   751					if(left != N)
   752						left->type = n->type;
   753					n->right = N;
   754					if(n->embedded && n->type != T) {
   755						t1 = n->type;
   756						if(t1->sym == S && isptr[t1->etype]) {
   757							t1 = t1->type;
   758							if(t1->etype == TINTER)
   759								yyerror("embedded type cannot be a pointer to interface");
   760						}
   761						if(isptr[t1->etype])
   762							yyerror("embedded type cannot be a pointer");
   763						else if(t1->etype == TFORW && t1->embedlineno == 0)
   764							t1->embedlineno = lineno;
   765					}
   766				}
   767			}
   768	
   769			if(n->type == T) {
   770				// assume error already printed
   771				continue;
   772			}
   773	
   774			switch(n->val.ctype) {
   775			case CTSTR:
   776				if(et != TSTRUCT)
   777					yyerror("interface method cannot have annotation");
   778				note = n->val.u.sval;
   779				break;
   780			default:
   781				if(et != TSTRUCT)
   782					yyerror("interface method cannot have annotation");
   783				else
   784					yyerror("field annotation must be string");
   785			case CTxxx:
   786				note = nil;
   787				break;
   788			}
   789	
   790			if(et == TINTER && left == N) {
   791				// embedded interface - inline the methods
   792				if(n->type->etype != TINTER) {
   793					if(n->type->etype == TFORW)
   794						yyerror("interface type loop involving %T", n->type);
   795					else
   796						yyerror("interface contains embedded non-interface %T", n->type);
   797					continue;
   798				}
   799				for(t1=n->type->type; t1!=T; t1=t1->down) {
   800					f = typ(TFIELD);
   801					f->type = t1->type;
   802					f->width = BADWIDTH;
   803					f->nname = newname(t1->sym);
   804					f->sym = t1->sym;
   805					for(t2=*t0; t2!=T; t2=t2->down) {
   806						if(t2->sym == f->sym) {
   807							yyerror("duplicate method %s", t2->sym->name);
   808							break;
   809						}
   810					}
   811					*t = f;
   812					t = &f->down;
   813				}
   814				continue;
   815			}
   816	
   817			f = typ(TFIELD);
   818			f->type = n->type;
   819			f->note = note;
   820			f->width = BADWIDTH;
   821			f->isddd = n->isddd;
   822	
   823			if(left != N && left->op == ONAME) {
   824				f->nname = left;
   825				f->embedded = n->embedded;
   826				f->sym = f->nname->sym;
   827				if(importpkg && !exportname(f->sym->name))
   828					f->sym = pkglookup(f->sym->name, structpkg);
   829				if(f->sym && !isblank(f->nname)) {
   830					for(t1=*t0; t1!=T; t1=t1->down) {
   831						if(t1->sym == f->sym) {
   832							yyerror("duplicate %s %s", what, t1->sym->name);
   833							break;
   834						}
   835					}
   836				}
   837			}
   838	
   839			*t = f;
   840			t = &f->down;
   841		}
   842	
   843		*t = T;
   844		lineno = lno;
   845		return t;
   846	}
   847	
   848	Type*
   849	dostruct(NodeList *l, int et)
   850	{
   851		Type *t;
   852		int funarg;
   853	
   854		/*
   855		 * convert a parsed id/type list into
   856		 * a type for struct/interface/arglist
   857		 */
   858	
   859		funarg = 0;
   860		if(et == TFUNC) {
   861			funarg = 1;
   862			et = TSTRUCT;
   863		}
   864		t = typ(et);
   865		t->funarg = funarg;
   866		stotype(l, et, &t->type, funarg);
   867		if(t->type == T && l != nil) {
   868			t->broke = 1;
   869			return t;
   870		}
   871		if(et == TINTER)
   872			t = sortinter(t);
   873		if(!funarg)
   874			checkwidth(t);
   875		return t;
   876	}
   877	
   878	
   879	Node*
   880	embedded(Sym *s)
   881	{
   882		Node *n;
   883		char *name;
   884	
   885		// Names sometimes have disambiguation junk
   886		// appended after a center dot.  Discard it when
   887		// making the name for the embedded struct field.
   888		enum { CenterDot = 0xB7 };
   889		name = s->name;
   890		if(utfrune(s->name, CenterDot)) {
   891			name = strdup(s->name);
   892			*utfrune(name, CenterDot) = 0;
   893		}
   894	
   895		n = newname(lookup(name));
   896		n = nod(ODCLFIELD, n, oldname(s));
   897		n->embedded = 1;
   898		return n;
   899	}
   900	
   901	/*
   902	 * check that the list of declarations is either all anonymous or all named
   903	 */
   904	
   905	static Node*
   906	findtype(NodeList *l)
   907	{
   908		for(; l; l=l->next)
   909			if(l->n->op == OKEY)
   910				return l->n->right;
   911		return N;
   912	}
   913	
   914	NodeList*
   915	checkarglist(NodeList *all, int input)
   916	{
   917		int named;
   918		Node *n, *t, *nextt;
   919		NodeList *l;
   920	
   921		named = 0;
   922		for(l=all; l; l=l->next) {
   923			if(l->n->op == OKEY) {
   924				named = 1;
   925				break;
   926			}
   927		}
   928		if(named) {
   929			n = N;
   930			for(l=all; l; l=l->next) {
   931				n = l->n;
   932				if(n->op != OKEY && n->sym == S) {
   933					yyerror("mixed named and unnamed function parameters");
   934					break;
   935				}
   936			}
   937			if(l == nil && n != N && n->op != OKEY)
   938				yyerror("final function parameter must have type");
   939		}
   940	
   941		nextt = nil;
   942		for(l=all; l; l=l->next) {
   943			// can cache result from findtype to avoid
   944			// quadratic behavior here, but unlikely to matter.
   945			n = l->n;
   946			if(named) {
   947				if(n->op == OKEY) {
   948					t = n->right;
   949					n = n->left;
   950					nextt = nil;
   951				} else {
   952					if(nextt == nil)
   953						nextt = findtype(l);
   954					t = nextt;
   955				}
   956			} else {
   957				t = n;
   958				n = N;
   959			}
   960			if(n != N && n->sym == S) {
   961				t = n;
   962				n = N;
   963			}
   964			if(n != N)
   965				n = newname(n->sym);
   966			n = nod(ODCLFIELD, n, t);
   967			if(n->right != N && n->right->op == ODDD) {
   968				if(!input)
   969					yyerror("cannot use ... in output argument list");
   970				else if(l->next != nil)
   971					yyerror("can only use ... as final argument in list");
   972				n->right->op = OTARRAY;
   973				n->right->right = n->right->left;
   974				n->right->left = N;
   975				n->isddd = 1;
   976				if(n->left != N)
   977					n->left->isddd = 1;
   978			}
   979			l->n = n;
   980		}
   981		return all;
   982	}
   983	
   984	
   985	Node*
   986	fakethis(void)
   987	{
   988		Node *n;
   989	
   990		n = nod(ODCLFIELD, N, typenod(ptrto(typ(TSTRUCT))));
   991		return n;
   992	}
   993	
   994	/*
   995	 * Is this field a method on an interface?
   996	 * Those methods have an anonymous
   997	 * *struct{} as the receiver.
   998	 * (See fakethis above.)
   999	 */
  1000	int
  1001	isifacemethod(Type *f)
  1002	{
  1003		Type *rcvr;
  1004		Type *t;
  1005	
  1006		rcvr = getthisx(f)->type;
  1007		if(rcvr->sym != S)
  1008			return 0;
  1009		t = rcvr->type;
  1010		if(!isptr[t->etype])
  1011			return 0;
  1012		t = t->type;
  1013		if(t->sym != S || t->etype != TSTRUCT || t->type != T)
  1014			return 0;
  1015		return 1;
  1016	}
  1017	
  1018	/*
  1019	 * turn a parsed function declaration
  1020	 * into a type
  1021	 */
  1022	Type*
  1023	functype(Node *this, NodeList *in, NodeList *out)
  1024	{
  1025		Type *t;
  1026		NodeList *rcvr;
  1027	
  1028		t = typ(TFUNC);
  1029	
  1030		rcvr = nil;
  1031		if(this)
  1032			rcvr = list1(this);
  1033		t->type = dostruct(rcvr, TFUNC);
  1034		t->type->down = dostruct(out, TFUNC);
  1035		t->type->down->down = dostruct(in, TFUNC);
  1036	
  1037		if(this)
  1038			t->thistuple = 1;
  1039		t->outtuple = count(out);
  1040		t->intuple = count(in);
  1041		t->outnamed = t->outtuple > 0 && out->n->left != N;
  1042	
  1043		return t;
  1044	}
  1045	
  1046	Sym*
  1047	methodsym(Sym *nsym, Type *t0, int iface)
  1048	{
  1049		Sym *s;
  1050		char *p;
  1051		Type *t;
  1052		char *suffix;
  1053	
  1054		t = t0;
  1055		if(t == T)
  1056			goto bad;
  1057		s = t->sym;
  1058		if(s == S) {
  1059			if(!isptr[t->etype])
  1060				goto bad;
  1061			t = t->type;
  1062			if(t == T)
  1063				goto bad;
  1064			s = t->sym;
  1065			if(s == S)
  1066				goto bad;
  1067		}
  1068	
  1069		// if t0 == *t and t0 has a sym,
  1070		// we want to see *t, not t0, in the method name.
  1071		if(t != t0 && t0->sym)
  1072			t0 = ptrto(t);
  1073	
  1074		suffix = "";
  1075		if(iface) {
  1076			dowidth(t0);
  1077			if(t0->width < types[tptr]->width)
  1078				suffix = "·i";
  1079		}
  1080		if(t0->sym == S && isptr[t0->etype])
  1081			p = smprint("(%#hT).%s%s", t0, nsym->name, suffix);
  1082		else
  1083			p = smprint("%#hT.%s%s", t0, nsym->name, suffix);
  1084		s = pkglookup(p, s->pkg);
  1085		free(p);
  1086		return s;
  1087	
  1088	bad:
  1089		yyerror("illegal receiver type: %T", t0);
  1090		return S;
  1091	}
  1092	
  1093	Node*
  1094	methodname(Node *n, Type *t)
  1095	{
  1096		Sym *s;
  1097	
  1098		s = methodsym(n->sym, t, 0);
  1099		if(s == S)
  1100			return n;
  1101		return newname(s);
  1102	}
  1103	
  1104	Node*
  1105	methodname1(Node *n, Node *t)
  1106	{
  1107		char *star;
  1108		char *p;
  1109	
  1110		star = nil;
  1111		if(t->op == OIND) {
  1112			star = "*";
  1113			t = t->left;
  1114		}
  1115		if(t->sym == S || isblank(n))
  1116			return newname(n->sym);
  1117		if(star)
  1118			p = smprint("(%s%S).%S", star, t->sym, n->sym);
  1119		else
  1120			p = smprint("%S.%S", t->sym, n->sym);
  1121		n = newname(pkglookup(p, t->sym->pkg));
  1122		free(p);
  1123		return n;
  1124	}
  1125	
  1126	/*
  1127	 * add a method, declared as a function,
  1128	 * n is fieldname, pa is base type, t is function type
  1129	 */
  1130	void
  1131	addmethod(Sym *sf, Type *t, int local)
  1132	{
  1133		Type *f, *d, *pa;
  1134		Node *n;
  1135	
  1136		pa = nil;
  1137	
  1138		// get field sym
  1139		if(sf == S)
  1140			fatal("no method symbol");
  1141	
  1142		// get parent type sym
  1143		pa = getthisx(t)->type;	// ptr to this structure
  1144		if(pa == T) {
  1145			yyerror("missing receiver");
  1146			return;
  1147		}
  1148	
  1149		pa = pa->type;
  1150		f = methtype(pa);
  1151		if(f == T) {
  1152			t = pa;
  1153			if(t != T) {
  1154				if(isptr[t->etype]) {
  1155					if(t->sym != S) {
  1156						yyerror("invalid receiver type %T (%T is a pointer type)", pa, t);
  1157						return;
  1158					}
  1159					t = t->type;
  1160				}
  1161			}
  1162			if(t != T) {
  1163				if(t->sym == S) {
  1164					yyerror("invalid receiver type %T (%T is an unnamed type)", pa, t);
  1165					return;
  1166				}
  1167				if(isptr[t->etype]) {
  1168					yyerror("invalid receiver type %T (%T is a pointer type)", pa, t);
  1169					return;
  1170				}
  1171				if(t->etype == TINTER) {
  1172					yyerror("invalid receiver type %T (%T is an interface type)", pa, t);
  1173					return;
  1174				}
  1175			}
  1176			// Should have picked off all the reasons above,
  1177			// but just in case, fall back to generic error.
  1178			yyerror("invalid receiver type %T", pa);
  1179			return;
  1180		}
  1181	
  1182		pa = f;
  1183		if(importpkg && !exportname(sf->name))
  1184			sf = pkglookup(sf->name, importpkg);
  1185	
  1186		n = nod(ODCLFIELD, newname(sf), N);
  1187		n->type = t;
  1188	
  1189		d = T;	// last found
  1190		for(f=pa->method; f!=T; f=f->down) {
  1191			d = f;
  1192			if(f->etype != TFIELD)
  1193				fatal("addmethod: not TFIELD: %N", f);
  1194			if(strcmp(sf->name, f->sym->name) != 0)
  1195				continue;
  1196			if(!eqtype(t, f->type))
  1197				yyerror("method redeclared: %T.%S\n\t%T\n\t%T", pa, sf, f->type, t);
  1198			return;
  1199		}
  1200	
  1201		if(local && !pa->local) {
  1202			// defining method on non-local type.
  1203			yyerror("cannot define new methods on non-local type %T", pa);
  1204			return;
  1205		}
  1206	
  1207		if(d == T)
  1208			stotype(list1(n), 0, &pa->method, 0);
  1209		else
  1210			stotype(list1(n), 0, &d->down, 0);
  1211		return;
  1212	}
  1213	
  1214	void
  1215	funccompile(Node *n, int isclosure)
  1216	{
  1217		stksize = BADWIDTH;
  1218		maxarg = 0;
  1219	
  1220		if(n->type == T) {
  1221			if(nerrors == 0)
  1222				fatal("funccompile missing type");
  1223			return;
  1224		}
  1225	
  1226		// assign parameter offsets
  1227		checkwidth(n->type);
  1228		
  1229		// record offset to actual frame pointer.
  1230		// for closure, have to skip over leading pointers and PC slot.
  1231		nodfp->xoffset = 0;
  1232		if(isclosure) {
  1233			NodeList *l;
  1234			for(l=n->nname->ntype->list; l; l=l->next) {
  1235				nodfp->xoffset += widthptr;
  1236				if(l->n->left == N)	// found slot for PC
  1237					break;
  1238			}
  1239		}
  1240	
  1241		if(curfn)
  1242			fatal("funccompile %S inside %S", n->nname->sym, curfn->nname->sym);
  1243	
  1244		stksize = 0;
  1245		dclcontext = PAUTO;
  1246		funcdepth = n->funcdepth + 1;
  1247		compile(n);
  1248		curfn = nil;
  1249		funcdepth = 0;
  1250		dclcontext = PEXTERN;
  1251	}
  1252	
  1253	
  1254	

release.r60.3. Except as noted, this content is licensed under a Creative Commons Attribution 3.0 License.