github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/src/cmd/cc/dcl.c (about)

     1  // Inferno utils/cc/dcl.c
     2  // http://code.google.com/p/inferno-os/source/browse/utils/cc/dcl.c
     3  //
     4  //	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
     5  //	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
     6  //	Portions Copyright © 1997-1999 Vita Nuova Limited
     7  //	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
     8  //	Portions Copyright © 2004,2006 Bruce Ellis
     9  //	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
    10  //	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
    11  //	Portions Copyright © 2009 The Go Authors.  All rights reserved.
    12  //
    13  // Permission is hereby granted, free of charge, to any person obtaining a copy
    14  // of this software and associated documentation files (the "Software"), to deal
    15  // in the Software without restriction, including without limitation the rights
    16  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    17  // copies of the Software, and to permit persons to whom the Software is
    18  // furnished to do so, subject to the following conditions:
    19  //
    20  // The above copyright notice and this permission notice shall be included in
    21  // all copies or substantial portions of the Software.
    22  //
    23  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    24  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    25  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
    26  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    27  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    28  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    29  // THE SOFTWARE.
    30  
    31  #include <u.h>
    32  #include "cc.h"
    33  
    34  Node*
    35  dodecl(void (*f)(int,Type*,Sym*), int c, Type *t, Node *n)
    36  {
    37  	Sym *s;
    38  	Node *n1;
    39  	int32 v;
    40  
    41  	nearln = lineno;
    42  	lastfield = 0;
    43  
    44  loop:
    45  	if(n != Z)
    46  	switch(n->op) {
    47  	default:
    48  		diag(n, "unknown declarator: %O", n->op);
    49  		break;
    50  
    51  	case OARRAY:
    52  		t = typ(TARRAY, t);
    53  		t->width = 0;
    54  		n1 = n->right;
    55  		n = n->left;
    56  		if(n1 != Z) {
    57  			complex(n1);
    58  			v = -1;
    59  			if(n1->op == OCONST)
    60  				v = n1->vconst;
    61  			if(v <= 0) {
    62  				diag(n, "array size must be a positive constant");
    63  				v = 1;
    64  			}
    65  			t->width = v * t->link->width;
    66  		}
    67  		goto loop;
    68  
    69  	case OIND:
    70  		t = typ(TIND, t);
    71  		t->garb = n->garb;
    72  		n = n->left;
    73  		goto loop;
    74  
    75  	case OFUNC:
    76  		t = typ(TFUNC, t);
    77  		t->down = fnproto(n);
    78  		n = n->left;
    79  		goto loop;
    80  
    81  	case OBIT:
    82  		n1 = n->right;
    83  		complex(n1);
    84  		lastfield = -1;
    85  		if(n1->op == OCONST)
    86  			lastfield = n1->vconst;
    87  		if(lastfield < 0) {
    88  			diag(n, "field width must be non-negative constant");
    89  			lastfield = 1;
    90  		}
    91  		if(lastfield == 0) {
    92  			lastbit = 0;
    93  			firstbit = 1;
    94  			if(n->left != Z) {
    95  				diag(n, "zero width named field");
    96  				lastfield = 1;
    97  			}
    98  		}
    99  		if(!typei[t->etype]) {
   100  			diag(n, "field type must be int-like");
   101  			t = types[TINT];
   102  			lastfield = 1;
   103  		}
   104  		if(lastfield > tfield->width*8) {
   105  			diag(n, "field width larger than field unit");
   106  			lastfield = 1;
   107  		}
   108  		lastbit += lastfield;
   109  		if(lastbit > tfield->width*8) {
   110  			lastbit = lastfield;
   111  			firstbit = 1;
   112  		}
   113  		n = n->left;
   114  		goto loop;
   115  
   116  	case ONAME:
   117  		if(f == NODECL)
   118  			break;
   119  		s = n->sym;
   120  		(*f)(c, t, s);
   121  		if(s->class == CLOCAL)
   122  			s = mkstatic(s);
   123  		if(dataflag) {
   124  			s->dataflag = dataflag;
   125  			dataflag = 0;
   126  		}
   127  		firstbit = 0;
   128  		n->sym = s;
   129  		n->type = s->type;
   130  		n->xoffset = s->offset;
   131  		n->class = s->class;
   132  		n->etype = TVOID;
   133  		if(n->type != T)
   134  			n->etype = n->type->etype;
   135  		if(debug['d'])
   136  			dbgdecl(s);
   137  		acidvar(s);
   138  		godefvar(s);
   139  		s->varlineno = lineno;
   140  		break;
   141  	}
   142  	lastdcl = t;
   143  	return n;
   144  }
   145  
   146  Sym*
   147  mkstatic(Sym *s)
   148  {
   149  	Sym *s1;
   150  
   151  	if(s->class != CLOCAL)
   152  		return s;
   153  	snprint(symb, NSYMB, "%s$%d", s->name, s->block);
   154  	s1 = lookup();
   155  	if(s1->class != CSTATIC) {
   156  		s1->type = s->type;
   157  		s1->offset = s->offset;
   158  		s1->block = s->block;
   159  		s1->class = CSTATIC;
   160  	}
   161  	return s1;
   162  }
   163  
   164  /*
   165   * make a copy of a typedef
   166   * the problem is to split out incomplete
   167   * arrays so that it is in the variable
   168   * rather than the typedef.
   169   */
   170  Type*
   171  tcopy(Type *t)
   172  {
   173  	Type *tl, *tx;
   174  	int et;
   175  
   176  	if(t == T)
   177  		return t;
   178  	et = t->etype;
   179  	if(typesu[et])
   180  		return t;
   181  	tl = tcopy(t->link);
   182  	if(tl != t->link ||
   183  	  (et == TARRAY && t->width == 0)) {
   184  		tx = copytyp(t);
   185  		tx->link = tl;
   186  		return tx;
   187  	}
   188  	return t;
   189  }
   190  
   191  Node*
   192  doinit(Sym *s, Type *t, int32 o, Node *a)
   193  {
   194  	Node *n;
   195  
   196  	if(t == T)
   197  		return Z;
   198  	if(s->class == CEXTERN) {
   199  		s->class = CGLOBL;
   200  		if(debug['d'])
   201  			dbgdecl(s);
   202  	}
   203  	if(debug['i']) {
   204  		print("t = %T; o = %d; n = %s\n", t, o, s->name);
   205  		prtree(a, "doinit value");
   206  	}
   207  
   208  
   209  	n = initlist;
   210  	if(a->op == OINIT)
   211  		a = a->left;
   212  	initlist = a;
   213  
   214  	a = init1(s, t, o, 0);
   215  	if(initlist != Z)
   216  		diag(initlist, "more initializers than structure: %s",
   217  			s->name);
   218  	initlist = n;
   219  
   220  	return a;
   221  }
   222  
   223  /*
   224   * get next major operator,
   225   * dont advance initlist.
   226   */
   227  Node*
   228  peekinit(void)
   229  {
   230  	Node *a;
   231  
   232  	a = initlist;
   233  
   234  loop:
   235  	if(a == Z)
   236  		return a;
   237  	if(a->op == OLIST) {
   238  		a = a->left;
   239  		goto loop;
   240  	}
   241  	return a;
   242  }
   243  
   244  /*
   245   * consume and return next element on
   246   * initlist. expand strings.
   247   */
   248  Node*
   249  nextinit(void)
   250  {
   251  	Node *a, *b, *n;
   252  
   253  	a = initlist;
   254  	n = Z;
   255  
   256  	if(a == Z)
   257  		return a;
   258  	if(a->op == OLIST) {
   259  		n = a->right;
   260  		a = a->left;
   261  	}
   262  	if(a->op == OUSED) {
   263  		a = a->left;
   264  		b = new(OCONST, Z, Z);
   265  		b->type = a->type->link;
   266  		if(a->op == OSTRING) {
   267  			b->vconst = convvtox(*a->cstring, TCHAR);
   268  			a->cstring++;
   269  		}
   270  		if(a->op == OLSTRING) {
   271  			b->vconst = convvtox(*a->rstring, TUSHORT);
   272  			a->rstring++;
   273  		}
   274  		a->type->width -= b->type->width;
   275  		if(a->type->width <= 0)
   276  			initlist = n;
   277  		return b;
   278  	}
   279  	initlist = n;
   280  	return a;
   281  }
   282  
   283  int
   284  isstruct(Node *a, Type *t)
   285  {
   286  	Node *n;
   287  
   288  	switch(a->op) {
   289  	case ODOTDOT:
   290  		n = a->left;
   291  		if(n && n->type && sametype(n->type, t))
   292  			return 1;
   293  	case OSTRING:
   294  	case OLSTRING:
   295  	case OCONST:
   296  	case OINIT:
   297  	case OELEM:
   298  		return 0;
   299  	}
   300  
   301  	n = new(ODOTDOT, Z, Z);
   302  	*n = *a;
   303  
   304  	/*
   305  	 * ODOTDOT is a flag for tcom
   306  	 * a second tcom will not be performed
   307  	 */
   308  	a->op = ODOTDOT;
   309  	a->left = n;
   310  	a->right = Z;
   311  
   312  	if(tcom(n))
   313  		return 0;
   314  
   315  	if(sametype(n->type, t))
   316  		return 1;
   317  	return 0;
   318  }
   319  
   320  Node*
   321  init1(Sym *s, Type *t, int32 o, int exflag)
   322  {
   323  	Node *a, *l, *r, nod;
   324  	Type *t1;
   325  	int32 e, w, so, mw;
   326  
   327  	a = peekinit();
   328  	if(a == Z)
   329  		return Z;
   330  
   331  	if(debug['i']) {
   332  		print("t = %T; o = %d; n = %s\n", t, o, s->name);
   333  		prtree(a, "init1 value");
   334  	}
   335  
   336  	if(exflag && a->op == OINIT)
   337  		return doinit(s, t, o, nextinit());
   338  
   339  	switch(t->etype) {
   340  	default:
   341  		diag(Z, "unknown type in initialization: %T to: %s", t, s->name);
   342  		return Z;
   343  
   344  	case TCHAR:
   345  	case TUCHAR:
   346  	case TINT:
   347  	case TUINT:
   348  	case TSHORT:
   349  	case TUSHORT:
   350  	case TLONG:
   351  	case TULONG:
   352  	case TVLONG:
   353  	case TUVLONG:
   354  	case TFLOAT:
   355  	case TDOUBLE:
   356  	case TIND:
   357  	single:
   358  		if(a->op == OARRAY || a->op == OELEM)
   359  			return Z;
   360  
   361  		a = nextinit();
   362  		if(a == Z)
   363  			return Z;
   364  
   365  		if(t->nbits)
   366  			diag(Z, "cannot initialize bitfields");
   367  		if(s->class == CAUTO) {
   368  			l = new(ONAME, Z, Z);
   369  			l->sym = s;
   370  			l->type = t;
   371  			l->etype = TVOID;
   372  			if(s->type)
   373  				l->etype = s->type->etype;
   374  			l->xoffset = s->offset + o;
   375  			l->class = s->class;
   376  
   377  			l = new(OASI, l, a);
   378  			return l;
   379  		}
   380  
   381  		complex(a);
   382  		if(a->type == T)
   383  			return Z;
   384  
   385  		if(a->op == OCONST) {
   386  			if(vconst(a) && t->etype == TIND && a->type && a->type->etype != TIND){
   387  				diag(a, "initialize pointer to an integer: %s", s->name);
   388  				return Z;
   389  			}
   390  			if(!sametype(a->type, t)) {
   391  				/* hoop jumping to save malloc */
   392  				if(nodcast == Z)
   393  					nodcast = new(OCAST, Z, Z);
   394  				nod = *nodcast;
   395  				nod.left = a;
   396  				nod.type = t;
   397  				nod.lineno = a->lineno;
   398  				complex(&nod);
   399  				if(nod.type)
   400  					*a = nod;
   401  			}
   402  			if(a->op != OCONST) {
   403  				diag(a, "initializer is not a constant: %s",
   404  					s->name);
   405  				return Z;
   406  			}
   407  			if(vconst(a) == 0)
   408  				return Z;
   409  			goto gext;
   410  		}
   411  		if(t->etype == TIND) {
   412  			while(a->op == OCAST) {
   413  				warn(a, "CAST in initialization ignored");
   414  				a = a->left;
   415  			}
   416  			if(!sametype(t, a->type)) {
   417  				diag(a, "initialization of incompatible pointers: %s\n%T and %T",
   418  					s->name, t, a->type);
   419  			}
   420  			if(a->op == OADDR)
   421  				a = a->left;
   422  			goto gext;
   423  		}
   424  
   425  		while(a->op == OCAST)
   426  			a = a->left;
   427  		if(a->op == OADDR) {
   428  			warn(a, "initialize pointer to an integer: %s", s->name);
   429  			a = a->left;
   430  			goto gext;
   431  		}
   432  		diag(a, "initializer is not a constant: %s", s->name);
   433  		return Z;
   434  
   435  	gext:
   436  		gextern(s, a, o, t->width);
   437  
   438  		return Z;
   439  
   440  	case TARRAY:
   441  		w = t->link->width;
   442  		if(a->op == OSTRING || a->op == OLSTRING)
   443  		if(typei[t->link->etype]) {
   444  			/*
   445  			 * get rid of null if sizes match exactly
   446  			 */
   447  			a = nextinit();
   448  			mw = t->width/w;
   449  			so = a->type->width/a->type->link->width;
   450  			if(mw && so > mw) {
   451  				if(so != mw+1)
   452  					diag(a, "string initialization larger than array");
   453  				a->type->width -= a->type->link->width;
   454  			}
   455  
   456  			/*
   457  			 * arrange strings to be expanded
   458  			 * inside OINIT braces.
   459  			 */
   460  			a = new(OUSED, a, Z);
   461  			return doinit(s, t, o, a);
   462  		}
   463  
   464  		mw = -w;
   465  		l = Z;
   466  		for(e=0;;) {
   467  			/*
   468  			 * peek ahead for element initializer
   469  			 */
   470  			a = peekinit();
   471  			if(a == Z)
   472  				break;
   473  			if(a->op == OELEM && t->link->etype != TSTRUCT)
   474  				break;
   475  			if(a->op == OARRAY) {
   476  				if(e && exflag)
   477  					break;
   478  				a = nextinit();
   479  				r = a->left;
   480  				complex(r);
   481  				if(r->op != OCONST) {
   482  					diag(r, "initializer subscript must be constant");
   483  					return Z;
   484  				}
   485  				e = r->vconst;
   486  				if(t->width != 0)
   487  					if(e < 0 || e*w >= t->width) {
   488  						diag(a, "initialization index out of range: %d", e);
   489  						continue;
   490  					}
   491  			}
   492  
   493  			so = e*w;
   494  			if(so > mw)
   495  				mw = so;
   496  			if(t->width != 0)
   497  				if(mw >= t->width)
   498  					break;
   499  			r = init1(s, t->link, o+so, 1);
   500  			l = newlist(l, r);
   501  			e++;
   502  		}
   503  		if(t->width == 0)
   504  			t->width = mw+w;
   505  		return l;
   506  
   507  	case TUNION:
   508  	case TSTRUCT:
   509  		/*
   510  		 * peek ahead to find type of rhs.
   511  		 * if its a structure, then treat
   512  		 * this element as a variable
   513  		 * rather than an aggregate.
   514  		 */
   515  		if(isstruct(a, t))
   516  			goto single;
   517  
   518  		if(t->width <= 0) {
   519  			diag(Z, "incomplete structure: %s", s->name);
   520  			return Z;
   521  		}
   522  		l = Z;
   523  
   524  	again:
   525  		for(t1 = t->link; t1 != T; t1 = t1->down) {
   526  			if(a->op == OARRAY && t1->etype != TARRAY)
   527  				break;
   528  			if(a->op == OELEM) {
   529  				if(t1->sym != a->sym)
   530  					continue;
   531  				nextinit();
   532  			}
   533  			r = init1(s, t1, o+t1->offset, 1);
   534  			l = newlist(l, r);
   535  			a = peekinit();
   536  			if(a == Z)
   537  				break;
   538  			if(a->op == OELEM)
   539  				goto again;
   540  		}
   541  		if(a && a->op == OELEM)
   542  			diag(a, "structure element not found %F", a);
   543  		return l;
   544  	}
   545  }
   546  
   547  Node*
   548  newlist(Node *l, Node *r)
   549  {
   550  	if(r == Z)
   551  		return l;
   552  	if(l == Z)
   553  		return r;
   554  	return new(OLIST, l, r);
   555  }
   556  
   557  void
   558  sualign(Type *t)
   559  {
   560  	Type *l;
   561  	int32 o, w, maxal;
   562  
   563  	o = 0;
   564  	maxal = 0;
   565  	switch(t->etype) {
   566  
   567  	case TSTRUCT:
   568  		t->offset = 0;
   569  		w = 0;
   570  		for(l = t->link; l != T; l = l->down) {
   571  			if(l->nbits) {
   572  				if(l->shift <= 0) {
   573  					l->shift = -l->shift;
   574  					w = xround(w, tfield->width);
   575  					o = w;
   576  					w += tfield->width;
   577  				}
   578  				l->offset = o;
   579  			} else {
   580  				if(l->width <= 0)
   581  				if(l->down != T)
   582  					if(l->sym)
   583  						diag(Z, "incomplete structure element: %s",
   584  							l->sym->name);
   585  					else
   586  						diag(Z, "incomplete structure element");
   587  				w = align(w, l, Ael1, &maxal);
   588  				l->offset = w;
   589  				w = align(w, l, Ael2, &maxal);
   590  			}
   591  		}
   592  		w = align(w, t, Asu2, &maxal);
   593  		t->width = w;
   594  		t->align = maxal;
   595  		acidtype(t);
   596  		godeftype(t);
   597  		return;
   598  
   599  	case TUNION:
   600  		t->offset = 0;
   601  		w = 0;
   602  		for(l = t->link; l != T; l = l->down) {
   603  			if(l->width <= 0)
   604  				if(l->sym)
   605  					diag(Z, "incomplete union element: %s",
   606  						l->sym->name);
   607  				else
   608  					diag(Z, "incomplete union element");
   609  			l->offset = 0;
   610  			l->shift = 0;
   611  			o = align(align(0, l, Ael1, &maxal), l, Ael2, &maxal);
   612  			if(o > w)
   613  				w = o;
   614  		}
   615  		w = align(w, t, Asu2, &maxal);
   616  		t->width = w;
   617  		t->align = maxal;
   618  		acidtype(t);
   619  		godeftype(t);
   620  		return;
   621  
   622  	default:
   623  		diag(Z, "unknown type in sualign: %T", t);
   624  		break;
   625  	}
   626  }
   627  
   628  int32
   629  xround(int32 v, int w)
   630  {
   631  	int r;
   632  
   633  	if(w <= 0 || w > 8) {
   634  		diag(Z, "rounding by %d", w);
   635  		w = 1;
   636  	}
   637  	r = v%w;
   638  	if(r)
   639  		v += w-r;
   640  	return v;
   641  }
   642  
   643  Type*
   644  ofnproto(Node *n)
   645  {
   646  	Type *tl, *tr, *t;
   647  
   648  	if(n == Z)
   649  		return T;
   650  	switch(n->op) {
   651  	case OLIST:
   652  		tl = ofnproto(n->left);
   653  		tr = ofnproto(n->right);
   654  		if(tl == T)
   655  			return tr;
   656  		tl->down = tr;
   657  		return tl;
   658  
   659  	case ONAME:
   660  		t = copytyp(n->sym->type);
   661  		t->down = T;
   662  		return t;
   663  	}
   664  	return T;
   665  }
   666  
   667  #define	ANSIPROTO	1
   668  #define	OLDPROTO	2
   669  
   670  void
   671  argmark(Node *n, int pass)
   672  {
   673  	Type *t;
   674  
   675  	autoffset = align(0, thisfn->link, Aarg0, nil);
   676  	stkoff = 0;
   677  	for(; n->left != Z; n = n->left) {
   678  		if(n->op != OFUNC || n->left->op != ONAME)
   679  			continue;
   680  		walkparam(n->right, pass);
   681  		if(pass != 0 && anyproto(n->right) == OLDPROTO) {
   682  			t = typ(TFUNC, n->left->sym->type->link);
   683  			t->down = typ(TOLD, T);
   684  			t->down->down = ofnproto(n->right);
   685  			tmerge(t, n->left->sym);
   686  			n->left->sym->type = t;
   687  		}
   688  		break;
   689  	}
   690  	autoffset = 0;
   691  	stkoff = 0;
   692  }
   693  
   694  void
   695  walkparam(Node *n, int pass)
   696  {
   697  	Sym *s;
   698  	Node *n1;
   699  
   700  	if(n != Z && n->op == OPROTO && n->left == Z && n->type == types[TVOID])
   701  		return;
   702  
   703  loop:
   704  	if(n == Z)
   705  		return;
   706  	switch(n->op) {
   707  	default:
   708  		diag(n, "argument not a name/prototype: %O", n->op);
   709  		break;
   710  
   711  	case OLIST:
   712  		walkparam(n->left, pass);
   713  		n = n->right;
   714  		goto loop;
   715  
   716  	case OPROTO:
   717  		for(n1 = n; n1 != Z; n1=n1->left)
   718  			if(n1->op == ONAME) {
   719  				if(pass == 0) {
   720  					s = n1->sym;
   721  					push1(s);
   722  					s->offset = -1;
   723  					break;
   724  				}
   725  				dodecl(pdecl, CPARAM, n->type, n->left);
   726  				break;
   727  			}
   728  		if(n1)
   729  			break;
   730  		if(pass == 0) {
   731  			/*
   732  			 * extension:
   733  			 *	allow no name in argument declaration
   734  			diag(Z, "no name in argument declaration");
   735  			 */
   736  			break;
   737  		}
   738  		dodecl(NODECL, CPARAM, n->type, n->left);
   739  		pdecl(CPARAM, lastdcl, S);
   740  		break;
   741  
   742  	case ODOTDOT:
   743  		break;
   744  	
   745  	case ONAME:
   746  		s = n->sym;
   747  		if(pass == 0) {
   748  			push1(s);
   749  			s->offset = -1;
   750  			break;
   751  		}
   752  		if(s->offset != -1) {
   753  			if(autoffset == 0) {
   754  				firstarg = s;
   755  				firstargtype = s->type;
   756  			}
   757  			autoffset = align(autoffset, s->type, Aarg1, nil);
   758  			s->offset = autoffset;
   759  			autoffset = align(autoffset, s->type, Aarg2, nil);
   760  		} else
   761  			dodecl(pdecl, CXXX, types[TINT], n);
   762  		break;
   763  	}
   764  }
   765  
   766  void
   767  markdcl(void)
   768  {
   769  	Decl *d;
   770  
   771  	blockno++;
   772  	d = push();
   773  	d->val = DMARK;
   774  	d->offset = autoffset;
   775  	d->block = autobn;
   776  	autobn = blockno;
   777  }
   778  
   779  Node*
   780  revertdcl(void)
   781  {
   782  	Decl *d;
   783  	Sym *s;
   784  	Node *n, *n1;
   785  
   786  	n = Z;
   787  	for(;;) {
   788  		d = dclstack;
   789  		if(d == D) {
   790  			diag(Z, "pop off dcl stack");
   791  			break;
   792  		}
   793  		dclstack = d->link;
   794  		s = d->sym;
   795  		switch(d->val) {
   796  		case DMARK:
   797  			autoffset = d->offset;
   798  			autobn = d->block;
   799  			return n;
   800  
   801  		case DAUTO:
   802  			if(debug['d'])
   803  				print("revert1 \"%s\"\n", s->name);
   804  			if(s->aused == 0) {
   805  				nearln = s->varlineno;
   806  				if(s->class == CAUTO)
   807  					warn(Z, "auto declared and not used: %s", s->name);
   808  				if(s->class == CPARAM)
   809  					warn(Z, "param declared and not used: %s", s->name);
   810  			}
   811  			if(s->type && (s->type->garb & GVOLATILE)) {
   812  				n1 = new(ONAME, Z, Z);
   813  				n1->sym = s;
   814  				n1->type = s->type;
   815  				n1->etype = TVOID;
   816  				if(n1->type != T)
   817  					n1->etype = n1->type->etype;
   818  				n1->xoffset = s->offset;
   819  				n1->class = s->class;
   820  
   821  				n1 = new(OADDR, n1, Z);
   822  				n1 = new(OUSED, n1, Z);
   823  				if(n == Z)
   824  					n = n1;
   825  				else
   826  					n = new(OLIST, n1, n);
   827  			}
   828  			s->type = d->type;
   829  			s->class = d->class;
   830  			s->offset = d->offset;
   831  			s->block = d->block;
   832  			s->varlineno = d->varlineno;
   833  			s->aused = d->aused;
   834  			break;
   835  
   836  		case DSUE:
   837  			if(debug['d'])
   838  				print("revert2 \"%s\"\n", s->name);
   839  			s->suetag = d->type;
   840  			s->sueblock = d->block;
   841  			break;
   842  
   843  		case DLABEL:
   844  			if(debug['d'])
   845  				print("revert3 \"%s\"\n", s->name);
   846  			if(s->label && s->label->addable == 0)
   847  				warn(s->label, "label declared and not used \"%s\"", s->name);
   848  			s->label = Z;
   849  			break;
   850  		}
   851  	}
   852  	return n;
   853  }
   854  
   855  Type*
   856  fnproto(Node *n)
   857  {
   858  	int r;
   859  
   860  	r = anyproto(n->right);
   861  	if(r == 0 || (r & OLDPROTO)) {
   862  		if(r & ANSIPROTO)
   863  			diag(n, "mixed ansi/old function declaration: %F", n->left);
   864  		return T;
   865  	}
   866  	return fnproto1(n->right);
   867  }
   868  
   869  int
   870  anyproto(Node *n)
   871  {
   872  	int r;
   873  
   874  	r = 0;
   875  
   876  loop:
   877  	if(n == Z)
   878  		return r;
   879  	switch(n->op) {
   880  	case OLIST:
   881  		r |= anyproto(n->left);
   882  		n = n->right;
   883  		goto loop;
   884  
   885  	case ODOTDOT:
   886  	case OPROTO:
   887  		return r | ANSIPROTO;
   888  	}
   889  	return r | OLDPROTO;
   890  }
   891  
   892  Type*
   893  fnproto1(Node *n)
   894  {
   895  	Type *t;
   896  
   897  	if(n == Z)
   898  		return T;
   899  	switch(n->op) {
   900  	case OLIST:
   901  		t = fnproto1(n->left);
   902  		if(t != T)
   903  			t->down = fnproto1(n->right);
   904  		return t;
   905  
   906  	case OPROTO:
   907  		lastdcl = T;
   908  		dodecl(NODECL, CXXX, n->type, n->left);
   909  		t = typ(TXXX, T);
   910  		if(lastdcl != T)
   911  			*t = *paramconv(lastdcl, 1);
   912  		return t;
   913  
   914  	case ONAME:
   915  		diag(n, "incomplete argument prototype");
   916  		return typ(TINT, T);
   917  
   918  	case ODOTDOT:
   919  		return typ(TDOT, T);
   920  	}
   921  	diag(n, "unknown op in fnproto");
   922  	return T;
   923  }
   924  
   925  void
   926  dbgdecl(Sym *s)
   927  {
   928  	print("decl \"%s\": C=%s [B=%d:O=%d] T=%T\n",
   929  		s->name, cnames[s->class], s->block, s->offset, s->type);
   930  }
   931  
   932  Decl*
   933  push(void)
   934  {
   935  	Decl *d;
   936  
   937  	d = alloc(sizeof(*d));
   938  	d->link = dclstack;
   939  	dclstack = d;
   940  	return d;
   941  }
   942  
   943  Decl*
   944  push1(Sym *s)
   945  {
   946  	Decl *d;
   947  
   948  	d = push();
   949  	d->sym = s;
   950  	d->val = DAUTO;
   951  	d->type = s->type;
   952  	d->class = s->class;
   953  	d->offset = s->offset;
   954  	d->block = s->block;
   955  	d->varlineno = s->varlineno;
   956  	d->aused = s->aused;
   957  	return d;
   958  }
   959  
   960  int
   961  sametype(Type *t1, Type *t2)
   962  {
   963  
   964  	if(t1 == t2)
   965  		return 1;
   966  	return rsametype(t1, t2, 5, 1);
   967  }
   968  
   969  int
   970  rsametype(Type *t1, Type *t2, int n, int f)
   971  {
   972  	int et;
   973  
   974  	n--;
   975  	for(;;) {
   976  		if(t1 == t2)
   977  			return 1;
   978  		if(t1 == T || t2 == T)
   979  			return 0;
   980  		if(n <= 0)
   981  			return 1;
   982  		et = t1->etype;
   983  		if(et != t2->etype)
   984  			return 0;
   985  		if(et == TFUNC) {
   986  			if(!rsametype(t1->link, t2->link, n, 0))
   987  				return 0;
   988  			t1 = t1->down;
   989  			t2 = t2->down;
   990  			while(t1 != T && t2 != T) {
   991  				if(t1->etype == TOLD) {
   992  					t1 = t1->down;
   993  					continue;
   994  				}
   995  				if(t2->etype == TOLD) {
   996  					t2 = t2->down;
   997  					continue;
   998  				}
   999  				while(t1 != T || t2 != T) {
  1000  					if(!rsametype(t1, t2, n, 0))
  1001  						return 0;
  1002  					t1 = t1->down;
  1003  					t2 = t2->down;
  1004  				}
  1005  				break;
  1006  			}
  1007  			return 1;
  1008  		}
  1009  		if(et == TARRAY)
  1010  			if(t1->width != t2->width && t1->width != 0 && t2->width != 0)
  1011  				return 0;
  1012  		if(typesu[et]) {
  1013  			if(t1->link == T)
  1014  				snap(t1);
  1015  			if(t2->link == T)
  1016  				snap(t2);
  1017  			t1 = t1->link;
  1018  			t2 = t2->link;
  1019  			for(;;) {
  1020  				if(t1 == t2)
  1021  					return 1;
  1022  				if(!rsametype(t1, t2, n, 0))
  1023  					return 0;
  1024  				t1 = t1->down;
  1025  				t2 = t2->down;
  1026  			}
  1027  		}
  1028  		t1 = t1->link;
  1029  		t2 = t2->link;
  1030  		if((f || !debug['V']) && et == TIND) {
  1031  			if(t1 != T && t1->etype == TVOID)
  1032  				return 1;
  1033  			if(t2 != T && t2->etype == TVOID)
  1034  				return 1;
  1035  		}
  1036  	}
  1037  }
  1038  
  1039  typedef struct Typetab Typetab;
  1040  
  1041  struct Typetab{
  1042  	int n;
  1043  	Type **a;
  1044  };
  1045  
  1046  static int
  1047  sigind(Type *t, Typetab *tt)
  1048  {
  1049  	int n;
  1050  	Type **a, **na, **p, **e;
  1051  
  1052  	n = tt->n;
  1053  	a = tt->a;
  1054  	e = a+n;
  1055  	/* linear search seems ok */
  1056  	for(p = a ; p < e; p++)
  1057  		if(sametype(*p, t))
  1058  			return p-a;
  1059  	if((n&15) == 0){
  1060  		na = malloc((n+16)*sizeof(Type*));
  1061  		if(na == nil) {
  1062  			print("%s: out of memory", argv0);
  1063  			errorexit();
  1064  		}
  1065  		memmove(na, a, n*sizeof(Type*));
  1066  		free(a);
  1067  		a = tt->a = na;
  1068  	}
  1069  	a[tt->n++] = t;
  1070  	return -1;
  1071  }
  1072  
  1073  static uint32
  1074  signat(Type *t, Typetab *tt)
  1075  {
  1076  	int i;
  1077  	Type *t1;
  1078  	int32 s;
  1079  
  1080  	s = 0;
  1081  	for(; t; t=t->link) {
  1082  		s = s*thash1 + thash[t->etype];
  1083  		if(t->garb&GINCOMPLETE)
  1084  			return s;
  1085  		switch(t->etype) {
  1086  		default:
  1087  			return s;
  1088  		case TARRAY:
  1089  			s = s*thash2 + 0;	/* was t->width */
  1090  			break;
  1091  		case TFUNC:
  1092  			for(t1=t->down; t1; t1=t1->down)
  1093  				s = s*thash3 + signat(t1, tt);
  1094  			break;
  1095  		case TSTRUCT:
  1096  		case TUNION:
  1097  			if((i = sigind(t, tt)) >= 0){
  1098  				s = s*thash2 + i;
  1099  				return s;
  1100  			}
  1101  			for(t1=t->link; t1; t1=t1->down)
  1102  				s = s*thash3 + signat(t1, tt);
  1103  			return s;
  1104  		case TIND:
  1105  			break;
  1106  		}
  1107  	}
  1108  	return s;
  1109  }
  1110  
  1111  uint32
  1112  signature(Type *t)
  1113  {
  1114  	uint32 s;
  1115  	Typetab tt;
  1116  
  1117  	tt.n = 0;
  1118  	tt.a = nil;
  1119  	s = signat(t, &tt);
  1120  	free(tt.a);
  1121  	return s;
  1122  }
  1123  
  1124  uint32
  1125  sign(Sym *s)
  1126  {
  1127  	uint32 v;
  1128  	Type *t;
  1129  
  1130  	if(s->sig == SIGINTERN)
  1131  		return SIGNINTERN;
  1132  	if((t = s->type) == T)
  1133  		return 0;
  1134  	v = signature(t);
  1135  	if(v == 0)
  1136  		v = SIGNINTERN;
  1137  	return v;
  1138  }
  1139  
  1140  void
  1141  snap(Type *t)
  1142  {
  1143  	if(typesu[t->etype])
  1144  	if(t->link == T && t->tag && t->tag->suetag) {
  1145  		t->link = t->tag->suetag->link;
  1146  		t->width = t->tag->suetag->width;
  1147  	}
  1148  }
  1149  
  1150  Type*
  1151  dotag(Sym *s, int et, int bn)
  1152  {
  1153  	Decl *d;
  1154  
  1155  	if(bn != 0 && bn != s->sueblock) {
  1156  		d = push();
  1157  		d->sym = s;
  1158  		d->val = DSUE;
  1159  		d->type = s->suetag;
  1160  		d->block = s->sueblock;
  1161  		s->suetag = T;
  1162  	}
  1163  	if(s->suetag == T) {
  1164  		s->suetag = typ(et, T);
  1165  		s->sueblock = autobn;
  1166  	}
  1167  	if(s->suetag->etype != et)
  1168  		diag(Z, "tag used for more than one type: %s",
  1169  			s->name);
  1170  	if(s->suetag->tag == S)
  1171  		s->suetag->tag = s;
  1172  	return s->suetag;
  1173  }
  1174  
  1175  Node*
  1176  dcllabel(Sym *s, int f)
  1177  {
  1178  	Decl *d, d1;
  1179  	Node *n;
  1180  
  1181  	n = s->label;
  1182  	if(n != Z) {
  1183  		if(f) {
  1184  			if(n->complex)
  1185  				diag(Z, "label reused: %s", s->name);
  1186  			n->complex = 1;	// declared
  1187  		} else
  1188  			n->addable = 1;	// used
  1189  		return n;
  1190  	}
  1191  
  1192  	d = push();
  1193  	d->sym = s;
  1194  	d->val = DLABEL;
  1195  	dclstack = d->link;
  1196  
  1197  	d1 = *firstdcl;
  1198  	*firstdcl = *d;
  1199  	*d = d1;
  1200  
  1201  	firstdcl->link = d;
  1202  	firstdcl = d;
  1203  
  1204  	n = new(OXXX, Z, Z);
  1205  	n->sym = s;
  1206  	n->complex = f;
  1207  	n->addable = !f;
  1208  	s->label = n;
  1209  
  1210  	if(debug['d'])
  1211  		dbgdecl(s);
  1212  	return n;
  1213  }
  1214  
  1215  Type*
  1216  paramconv(Type *t, int f)
  1217  {
  1218  
  1219  	switch(t->etype) {
  1220  	case TUNION:
  1221  	case TSTRUCT:
  1222  		if(t->width <= 0)
  1223  			diag(Z, "incomplete structure: %s", t->tag->name);
  1224  		break;
  1225  
  1226  	case TARRAY:
  1227  		t = typ(TIND, t->link);
  1228  		t->width = types[TIND]->width;
  1229  		break;
  1230  
  1231  	case TFUNC:
  1232  		t = typ(TIND, t);
  1233  		t->width = types[TIND]->width;
  1234  		break;
  1235  
  1236  	case TFLOAT:
  1237  		if(!f)
  1238  			t = types[TDOUBLE];
  1239  		break;
  1240  
  1241  	case TCHAR:
  1242  	case TSHORT:
  1243  		if(!f)
  1244  			t = types[TINT];
  1245  		break;
  1246  
  1247  	case TUCHAR:
  1248  	case TUSHORT:
  1249  		if(!f)
  1250  			t = types[TUINT];
  1251  		break;
  1252  	}
  1253  	return t;
  1254  }
  1255  
  1256  void
  1257  adecl(int c, Type *t, Sym *s)
  1258  {
  1259  
  1260  	if(c == CSTATIC)
  1261  		c = CLOCAL;
  1262  	if(t->etype == TFUNC) {
  1263  		if(c == CXXX)
  1264  			c = CEXTERN;
  1265  		if(c == CLOCAL)
  1266  			c = CSTATIC;
  1267  		if(c == CAUTO || c == CEXREG)
  1268  			diag(Z, "function cannot be %s %s", cnames[c], s->name);
  1269  	}
  1270  	if(c == CXXX)
  1271  		c = CAUTO;
  1272  	if(s) {
  1273  		if(s->class == CSTATIC)
  1274  			if(c == CEXTERN || c == CGLOBL) {
  1275  				warn(Z, "just say static: %s", s->name);
  1276  				c = CSTATIC;
  1277  			}
  1278  		if(s->class == CAUTO || s->class == CPARAM || s->class == CLOCAL)
  1279  		if(s->block == autobn)
  1280  			diag(Z, "auto redeclaration of: %s", s->name);
  1281  		if(c != CPARAM)
  1282  			push1(s);
  1283  		s->block = autobn;
  1284  		s->offset = 0;
  1285  		s->type = t;
  1286  		s->class = c;
  1287  		s->aused = 0;
  1288  	}
  1289  	switch(c) {
  1290  	case CAUTO:
  1291  		autoffset = align(autoffset, t, Aaut3, nil);
  1292  		stkoff = maxround(stkoff, autoffset);
  1293  		s->offset = -autoffset;
  1294  		break;
  1295  
  1296  	case CPARAM:
  1297  		if(autoffset == 0) {
  1298  			firstarg = s;
  1299  			firstargtype = t;
  1300  		}
  1301  		autoffset = align(autoffset, t, Aarg1, nil);
  1302  		if(s)
  1303  			s->offset = autoffset;
  1304  		autoffset = align(autoffset, t, Aarg2, nil);
  1305  		break;
  1306  	}
  1307  }
  1308  
  1309  void
  1310  pdecl(int c, Type *t, Sym *s)
  1311  {
  1312  	if(s && s->offset != -1) {
  1313  		diag(Z, "not a parameter: %s", s->name);
  1314  		return;
  1315  	}
  1316  	t = paramconv(t, c==CPARAM);
  1317  	if(c == CXXX)
  1318  		c = CPARAM;
  1319  	if(c != CPARAM) {
  1320  		diag(Z, "parameter cannot have class: %s", s->name);
  1321  		c = CPARAM;
  1322  	}
  1323  	adecl(c, t, s);
  1324  }
  1325  
  1326  void
  1327  xdecl(int c, Type *t, Sym *s)
  1328  {
  1329  	int32 o;
  1330  
  1331  	o = 0;
  1332  	switch(c) {
  1333  	case CEXREG:
  1334  		o = exreg(t);
  1335  		if(o == 0)
  1336  			c = CEXTERN;
  1337  		if(s->class == CGLOBL)
  1338  			c = CGLOBL;
  1339  		break;
  1340  
  1341  	case CEXTERN:
  1342  		if(s->class == CGLOBL)
  1343  			c = CGLOBL;
  1344  		break;
  1345  
  1346  	case CXXX:
  1347  		c = CGLOBL;
  1348  		if(s->class == CEXTERN)
  1349  			s->class = CGLOBL;
  1350  		break;
  1351  
  1352  	case CAUTO:
  1353  		diag(Z, "overspecified class: %s %s %s", s->name, cnames[c], cnames[s->class]);
  1354  		c = CEXTERN;
  1355  		break;
  1356  
  1357  	case CTYPESTR:
  1358  		if(!typesuv[t->etype]) {
  1359  			diag(Z, "typestr must be struct/union: %s", s->name);
  1360  			break;
  1361  		}
  1362  		dclfunct(t, s);
  1363  		break;
  1364  	}
  1365  
  1366  	if(s->class == CSTATIC)
  1367  		if(c == CEXTERN || c == CGLOBL) {
  1368  			warn(Z, "overspecified class: %s %s %s", s->name, cnames[c], cnames[s->class]);
  1369  			c = CSTATIC;
  1370  		}
  1371  	if(s->type != T)
  1372  		if(s->class != c || !sametype(t, s->type) || t->etype == TENUM) {
  1373  			diag(Z, "external redeclaration of: %s", s->name);
  1374  			Bprint(&diagbuf, "	%s %T %L\n", cnames[c], t, nearln);
  1375  			Bprint(&diagbuf, "	%s %T %L\n", cnames[s->class], s->type, s->varlineno);
  1376  		}
  1377  	tmerge(t, s);
  1378  	s->type = t;
  1379  	s->class = c;
  1380  	s->block = 0;
  1381  	s->offset = o;
  1382  }
  1383  
  1384  void
  1385  tmerge(Type *t1, Sym *s)
  1386  {
  1387  	Type *ta, *tb, *t2;
  1388  
  1389  	t2 = s->type;
  1390  	for(;;) {
  1391  		if(t1 == T || t2 == T || t1 == t2)
  1392  			break;
  1393  		if(t1->etype != t2->etype)
  1394  			break;
  1395  		switch(t1->etype) {
  1396  		case TFUNC:
  1397  			ta = t1->down;
  1398  			tb = t2->down;
  1399  			if(ta == T) {
  1400  				t1->down = tb;
  1401  				break;
  1402  			}
  1403  			if(tb == T)
  1404  				break;
  1405  			while(ta != T && tb != T) {
  1406  				if(ta == tb)
  1407  					break;
  1408  				/* ignore old-style flag */
  1409  				if(ta->etype == TOLD) {
  1410  					ta = ta->down;
  1411  					continue;
  1412  				}
  1413  				if(tb->etype == TOLD) {
  1414  					tb = tb->down;
  1415  					continue;
  1416  				}
  1417  				/* checking terminated by ... */
  1418  				if(ta->etype == TDOT && tb->etype == TDOT) {
  1419  					ta = T;
  1420  					tb = T;
  1421  					break;
  1422  				}
  1423  				if(!sametype(ta, tb))
  1424  					break;
  1425  				ta = ta->down;
  1426  				tb = tb->down;
  1427  			}
  1428  			if(ta != tb)
  1429  				diag(Z, "function inconsistently declared: %s", s->name);
  1430  
  1431  			/* take new-style over old-style */
  1432  			ta = t1->down;
  1433  			tb = t2->down;
  1434  			if(ta != T && ta->etype == TOLD)
  1435  				if(tb != T && tb->etype != TOLD)
  1436  					t1->down = tb;
  1437  			break;
  1438  
  1439  		case TARRAY:
  1440  			/* should we check array size change? */
  1441  			if(t2->width > t1->width)
  1442  				t1->width = t2->width;
  1443  			break;
  1444  
  1445  		case TUNION:
  1446  		case TSTRUCT:
  1447  			return;
  1448  		}
  1449  		t1 = t1->link;
  1450  		t2 = t2->link;
  1451  	}
  1452  }
  1453  
  1454  void
  1455  edecl(int c, Type *t, Sym *s)
  1456  {
  1457  	Type *t1;
  1458  
  1459  	if(s == S) {
  1460  		if(!typesu[t->etype])
  1461  			diag(Z, "unnamed structure element must be struct/union");
  1462  		if(c != CXXX)
  1463  			diag(Z, "unnamed structure element cannot have class");
  1464  	} else
  1465  		if(c != CXXX)
  1466  			diag(Z, "structure element cannot have class: %s", s->name);
  1467  	t1 = t;
  1468  	t = copytyp(t1);
  1469  	t->sym = s;
  1470  	t->down = T;
  1471  	if(lastfield) {
  1472  		t->shift = lastbit - lastfield;
  1473  		t->nbits = lastfield;
  1474  		if(firstbit)
  1475  			t->shift = -t->shift;
  1476  		if(typeu[t->etype])
  1477  			t->etype = tufield->etype;
  1478  		else
  1479  			t->etype = tfield->etype;
  1480  	}
  1481  	if(strf == T)
  1482  		strf = t;
  1483  	else
  1484  		strl->down = t;
  1485  	strl = t;
  1486  }
  1487  
  1488  /*
  1489   * this routine is very suspect.
  1490   * ansi requires the enum type to
  1491   * be represented as an 'int'
  1492   * this means that 0x81234567
  1493   * would be illegal. this routine
  1494   * makes signed and unsigned go
  1495   * to unsigned.
  1496   */
  1497  Type*
  1498  maxtype(Type *t1, Type *t2)
  1499  {
  1500  
  1501  	if(t1 == T)
  1502  		return t2;
  1503  	if(t2 == T)
  1504  		return t1;
  1505  	if(t1->etype > t2->etype)
  1506  		return t1;
  1507  	return t2;
  1508  }
  1509  
  1510  void
  1511  doenum(Sym *s, Node *n)
  1512  {
  1513  
  1514  	if(n) {
  1515  		complex(n);
  1516  		if(n->op != OCONST) {
  1517  			diag(n, "enum not a constant: %s", s->name);
  1518  			return;
  1519  		}
  1520  		en.cenum = n->type;
  1521  		en.tenum = maxtype(en.cenum, en.tenum);
  1522  
  1523  		if(!typefd[en.cenum->etype])
  1524  			en.lastenum = n->vconst;
  1525  		else
  1526  			en.floatenum = n->fconst;
  1527  	}
  1528  	if(dclstack)
  1529  		push1(s);
  1530  	xdecl(CXXX, types[TENUM], s);
  1531  
  1532  	if(en.cenum == T) {
  1533  		en.tenum = types[TINT];
  1534  		en.cenum = types[TINT];
  1535  		en.lastenum = 0;
  1536  	}
  1537  	s->tenum = en.cenum;
  1538  
  1539  	if(!typefd[s->tenum->etype]) {
  1540  		s->vconst = convvtox(en.lastenum, s->tenum->etype);
  1541  		en.lastenum++;
  1542  	} else {
  1543  		s->fconst = en.floatenum;
  1544  		en.floatenum++;
  1545  	}
  1546  
  1547  	if(debug['d'])
  1548  		dbgdecl(s);
  1549  	acidvar(s);
  1550  	godefvar(s);
  1551  }
  1552  
  1553  void
  1554  symadjust(Sym *s, Node *n, int32 del)
  1555  {
  1556  
  1557  	switch(n->op) {
  1558  	default:
  1559  		if(n->left)
  1560  			symadjust(s, n->left, del);
  1561  		if(n->right)
  1562  			symadjust(s, n->right, del);
  1563  		return;
  1564  
  1565  	case ONAME:
  1566  		if(n->sym == s)
  1567  			n->xoffset -= del;
  1568  		return;
  1569  
  1570  	case OCONST:
  1571  	case OSTRING:
  1572  	case OLSTRING:
  1573  	case OINDREG:
  1574  	case OREGISTER:
  1575  		return;
  1576  	}
  1577  }
  1578  
  1579  Node*
  1580  contig(Sym *s, Node *n, int32 v)
  1581  {
  1582  	Node *p, *r, *q, *m;
  1583  	int32 w;
  1584  	Type *zt;
  1585  
  1586  	if(debug['i']) {
  1587  		print("contig v = %d; s = %s\n", v, s->name);
  1588  		prtree(n, "doinit value");
  1589  	}
  1590  
  1591  	if(n == Z)
  1592  		goto no;
  1593  	w = s->type->width;
  1594  
  1595  	/*
  1596  	 * nightmare: an automatic array whose size
  1597  	 * increases when it is initialized
  1598  	 */
  1599  	if(v != w) {
  1600  		if(v != 0)
  1601  			diag(n, "automatic adjustable array: %s", s->name);
  1602  		v = s->offset;
  1603  		autoffset = align(autoffset, s->type, Aaut3, nil);
  1604  		s->offset = -autoffset;
  1605  		stkoff = maxround(stkoff, autoffset);
  1606  		symadjust(s, n, v - s->offset);
  1607  	}
  1608  	if(w <= ewidth[TIND])
  1609  		goto no;
  1610  	if(n->op == OAS)
  1611  		diag(Z, "oops in contig");
  1612  /*ZZZ this appears incorrect
  1613  need to check if the list completely covers the data.
  1614  if not, bail
  1615   */
  1616  	if(n->op == OLIST)
  1617  		goto no;
  1618  	if(n->op == OASI)
  1619  		if(n->left->type)
  1620  		if(n->left->type->width == w)
  1621  			goto no;
  1622  	while(w & (ewidth[TIND]-1))
  1623  		w++;
  1624  /*
  1625   * insert the following code, where long becomes vlong if pointers are fat
  1626   *
  1627  	*(long**)&X = (long*)((char*)X + sizeof(X));
  1628  	do {
  1629  		*(long**)&X -= 1;
  1630  		**(long**)&X = 0;
  1631  	} while(*(long**)&X);
  1632   */
  1633  
  1634  	for(q=n; q->op != ONAME; q=q->left)
  1635  		;
  1636  
  1637  	zt = ewidth[TIND] > ewidth[TLONG]? types[TVLONG]: types[TLONG];
  1638  
  1639  	p = new(ONAME, Z, Z);
  1640  	*p = *q;
  1641  	p->type = typ(TIND, zt);
  1642  	p->xoffset = s->offset;
  1643  
  1644  	r = new(ONAME, Z, Z);
  1645  	*r = *p;
  1646  	r = new(OPOSTDEC, r, Z);
  1647  
  1648  	q = new(ONAME, Z, Z);
  1649  	*q = *p;
  1650  	q = new(OIND, q, Z);
  1651  
  1652  	m = new(OCONST, Z, Z);
  1653  	m->vconst = 0;
  1654  	m->type = zt;
  1655  
  1656  	q = new(OAS, q, m);
  1657  
  1658  	r = new(OLIST, r, q);
  1659  
  1660  	q = new(ONAME, Z, Z);
  1661  	*q = *p;
  1662  	r = new(ODWHILE, q, r);
  1663  
  1664  	q = new(ONAME, Z, Z);
  1665  	*q = *p;
  1666  	q->type = q->type->link;
  1667  	q->xoffset += w;
  1668  	q = new(OADDR, q, 0);
  1669  
  1670  	q = new(OASI, p, q);
  1671  	r = new(OLIST, q, r);
  1672  
  1673  	n = new(OLIST, r, n);
  1674  
  1675  no:
  1676  	return n;
  1677  }