github.com/ader1990/go@v0.0.0-20140630135419-8c24447fa791/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, TRUNE);
   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  static int
   558  haspointers(Type *t)
   559  {
   560  	Type *fld;
   561  
   562  	switch(t->etype) {
   563  	case TSTRUCT:
   564  		for(fld = t->link; fld != T; fld = fld->down) {
   565  			if(haspointers(fld))
   566  				return 1;
   567  		}
   568  		return 0;
   569  	case TARRAY:
   570  		return haspointers(t->link);
   571  	case TFUNC:
   572  	case TIND:
   573  		return 1;
   574  	default:
   575  		return 0;
   576  	}
   577  }
   578  
   579  void
   580  sualign(Type *t)
   581  {
   582  	Type *l;
   583  	int32 o, w, maxal;
   584  
   585  	o = 0;
   586  	maxal = 0;
   587  	switch(t->etype) {
   588  
   589  	case TSTRUCT:
   590  		t->offset = 0;
   591  		w = 0;
   592  		for(l = t->link; l != T; l = l->down) {
   593  			if(l->nbits) {
   594  				if(l->shift <= 0) {
   595  					l->shift = -l->shift;
   596  					w = xround(w, tfield->width);
   597  					o = w;
   598  					w += tfield->width;
   599  				}
   600  				l->offset = o;
   601  			} else {
   602  				if(l->width <= 0)
   603  				if(l->down != T)
   604  					if(l->sym)
   605  						diag(Z, "incomplete structure element: %s",
   606  							l->sym->name);
   607  					else
   608  						diag(Z, "incomplete structure element");
   609  				w = align(w, l, Ael1, &maxal);
   610  				l->offset = w;
   611  				w = align(w, l, Ael2, &maxal);
   612  			}
   613  		}
   614  		w = align(w, t, Asu2, &maxal);
   615  		t->width = w;
   616  		t->align = maxal;
   617  		acidtype(t);
   618  		godeftype(t);
   619  		return;
   620  
   621  	case TUNION:
   622  		t->offset = 0;
   623  		w = 0;
   624  		for(l = t->link; l != T; l = l->down) {
   625  			if(l->width <= 0)
   626  				if(l->sym)
   627  					diag(Z, "incomplete union element: %s",
   628  						l->sym->name);
   629  				else
   630  					diag(Z, "incomplete union element");
   631  			l->offset = 0;
   632  			l->shift = 0;
   633  			if((debug['q'] || debug['Q']) && haspointers(l))
   634  				diag(Z, "precise garbage collector cannot handle unions with pointers");
   635  
   636  			o = align(align(0, l, Ael1, &maxal), l, Ael2, &maxal);
   637  			if(o > w)
   638  				w = o;
   639  		}
   640  		w = align(w, t, Asu2, &maxal);
   641  		t->width = w;
   642  		t->align = maxal;
   643  		acidtype(t);
   644  		godeftype(t);
   645  		return;
   646  
   647  	default:
   648  		diag(Z, "unknown type in sualign: %T", t);
   649  		break;
   650  	}
   651  }
   652  
   653  int32
   654  xround(int32 v, int w)
   655  {
   656  	int r;
   657  
   658  	if(w <= 0 || w > 8) {
   659  		diag(Z, "rounding by %d", w);
   660  		w = 1;
   661  	}
   662  	r = v%w;
   663  	if(r)
   664  		v += w-r;
   665  	return v;
   666  }
   667  
   668  Type*
   669  ofnproto(Node *n)
   670  {
   671  	Type *tl, *tr, *t;
   672  
   673  	if(n == Z)
   674  		return T;
   675  	switch(n->op) {
   676  	case OLIST:
   677  		tl = ofnproto(n->left);
   678  		tr = ofnproto(n->right);
   679  		if(tl == T)
   680  			return tr;
   681  		tl->down = tr;
   682  		return tl;
   683  
   684  	case ONAME:
   685  		t = copytyp(n->sym->type);
   686  		t->down = T;
   687  		return t;
   688  	}
   689  	return T;
   690  }
   691  
   692  #define	ANSIPROTO	1
   693  #define	OLDPROTO	2
   694  
   695  void
   696  argmark(Node *n, int pass)
   697  {
   698  	Type *t;
   699  
   700  	autoffset = align(0, thisfn->link, Aarg0, nil);
   701  	stkoff = 0;
   702  	for(; n->left != Z; n = n->left) {
   703  		if(n->op != OFUNC || n->left->op != ONAME)
   704  			continue;
   705  		walkparam(n->right, pass);
   706  		if(pass != 0 && anyproto(n->right) == OLDPROTO) {
   707  			t = typ(TFUNC, n->left->sym->type->link);
   708  			t->down = typ(TOLD, T);
   709  			t->down->down = ofnproto(n->right);
   710  			tmerge(t, n->left->sym);
   711  			n->left->sym->type = t;
   712  		}
   713  		break;
   714  	}
   715  	autoffset = 0;
   716  	stkoff = 0;
   717  }
   718  
   719  void
   720  walkparam(Node *n, int pass)
   721  {
   722  	Sym *s;
   723  	Node *n1;
   724  
   725  	if(n != Z && n->op == OPROTO && n->left == Z && n->type == types[TVOID])
   726  		return;
   727  
   728  loop:
   729  	if(n == Z)
   730  		return;
   731  	switch(n->op) {
   732  	default:
   733  		diag(n, "argument not a name/prototype: %O", n->op);
   734  		break;
   735  
   736  	case OLIST:
   737  		walkparam(n->left, pass);
   738  		n = n->right;
   739  		goto loop;
   740  
   741  	case OPROTO:
   742  		for(n1 = n; n1 != Z; n1=n1->left)
   743  			if(n1->op == ONAME) {
   744  				if(pass == 0) {
   745  					s = n1->sym;
   746  					push1(s);
   747  					s->offset = -1;
   748  					break;
   749  				}
   750  				dodecl(pdecl, CPARAM, n->type, n->left);
   751  				break;
   752  			}
   753  		if(n1)
   754  			break;
   755  		if(pass == 0) {
   756  			/*
   757  			 * extension:
   758  			 *	allow no name in argument declaration
   759  			diag(Z, "no name in argument declaration");
   760  			 */
   761  			break;
   762  		}
   763  		dodecl(NODECL, CPARAM, n->type, n->left);
   764  		pdecl(CPARAM, lastdcl, S);
   765  		break;
   766  
   767  	case ODOTDOT:
   768  		break;
   769  	
   770  	case ONAME:
   771  		s = n->sym;
   772  		if(pass == 0) {
   773  			push1(s);
   774  			s->offset = -1;
   775  			break;
   776  		}
   777  		if(s->offset != -1) {
   778  			if(autoffset == 0) {
   779  				firstarg = s;
   780  				firstargtype = s->type;
   781  			}
   782  			autoffset = align(autoffset, s->type, Aarg1, nil);
   783  			s->offset = autoffset;
   784  			autoffset = align(autoffset, s->type, Aarg2, nil);
   785  		} else
   786  			dodecl(pdecl, CXXX, types[TINT], n);
   787  		break;
   788  	}
   789  }
   790  
   791  void
   792  markdcl(void)
   793  {
   794  	Decl *d;
   795  
   796  	blockno++;
   797  	d = push();
   798  	d->val = DMARK;
   799  	d->offset = autoffset;
   800  	d->block = autobn;
   801  	autobn = blockno;
   802  }
   803  
   804  Node*
   805  revertdcl(void)
   806  {
   807  	Decl *d;
   808  	Sym *s;
   809  	Node *n, *n1;
   810  
   811  	n = Z;
   812  	for(;;) {
   813  		d = dclstack;
   814  		if(d == D) {
   815  			diag(Z, "pop off dcl stack");
   816  			break;
   817  		}
   818  		dclstack = d->link;
   819  		s = d->sym;
   820  		switch(d->val) {
   821  		case DMARK:
   822  			autoffset = d->offset;
   823  			autobn = d->block;
   824  			return n;
   825  
   826  		case DAUTO:
   827  			if(debug['d'])
   828  				print("revert1 \"%s\"\n", s->name);
   829  			if(s->aused == 0) {
   830  				nearln = s->varlineno;
   831  				if(s->class == CAUTO)
   832  					warn(Z, "auto declared and not used: %s", s->name);
   833  				if(s->class == CPARAM)
   834  					warn(Z, "param declared and not used: %s", s->name);
   835  			}
   836  			if(s->type && (s->type->garb & GVOLATILE)) {
   837  				n1 = new(ONAME, Z, Z);
   838  				n1->sym = s;
   839  				n1->type = s->type;
   840  				n1->etype = TVOID;
   841  				if(n1->type != T)
   842  					n1->etype = n1->type->etype;
   843  				n1->xoffset = s->offset;
   844  				n1->class = s->class;
   845  
   846  				n1 = new(OADDR, n1, Z);
   847  				n1 = new(OUSED, n1, Z);
   848  				if(n == Z)
   849  					n = n1;
   850  				else
   851  					n = new(OLIST, n1, n);
   852  			}
   853  			s->type = d->type;
   854  			s->class = d->class;
   855  			s->offset = d->offset;
   856  			s->block = d->block;
   857  			s->varlineno = d->varlineno;
   858  			s->aused = d->aused;
   859  			break;
   860  
   861  		case DSUE:
   862  			if(debug['d'])
   863  				print("revert2 \"%s\"\n", s->name);
   864  			s->suetag = d->type;
   865  			s->sueblock = d->block;
   866  			break;
   867  
   868  		case DLABEL:
   869  			if(debug['d'])
   870  				print("revert3 \"%s\"\n", s->name);
   871  			if(s->label && s->label->addable == 0)
   872  				warn(s->label, "label declared and not used \"%s\"", s->name);
   873  			s->label = Z;
   874  			break;
   875  		}
   876  	}
   877  	return n;
   878  }
   879  
   880  Type*
   881  fnproto(Node *n)
   882  {
   883  	int r;
   884  
   885  	r = anyproto(n->right);
   886  	if(r == 0 || (r & OLDPROTO)) {
   887  		if(r & ANSIPROTO)
   888  			diag(n, "mixed ansi/old function declaration: %F", n->left);
   889  		return T;
   890  	}
   891  	return fnproto1(n->right);
   892  }
   893  
   894  int
   895  anyproto(Node *n)
   896  {
   897  	int r;
   898  
   899  	r = 0;
   900  
   901  loop:
   902  	if(n == Z)
   903  		return r;
   904  	switch(n->op) {
   905  	case OLIST:
   906  		r |= anyproto(n->left);
   907  		n = n->right;
   908  		goto loop;
   909  
   910  	case ODOTDOT:
   911  	case OPROTO:
   912  		return r | ANSIPROTO;
   913  	}
   914  	return r | OLDPROTO;
   915  }
   916  
   917  Type*
   918  fnproto1(Node *n)
   919  {
   920  	Type *t;
   921  
   922  	if(n == Z)
   923  		return T;
   924  	switch(n->op) {
   925  	case OLIST:
   926  		t = fnproto1(n->left);
   927  		if(t != T)
   928  			t->down = fnproto1(n->right);
   929  		return t;
   930  
   931  	case OPROTO:
   932  		lastdcl = T;
   933  		dodecl(NODECL, CXXX, n->type, n->left);
   934  		t = typ(TXXX, T);
   935  		if(lastdcl != T)
   936  			*t = *paramconv(lastdcl, 1);
   937  		return t;
   938  
   939  	case ONAME:
   940  		diag(n, "incomplete argument prototype");
   941  		return typ(TINT, T);
   942  
   943  	case ODOTDOT:
   944  		return typ(TDOT, T);
   945  	}
   946  	diag(n, "unknown op in fnproto");
   947  	return T;
   948  }
   949  
   950  void
   951  dbgdecl(Sym *s)
   952  {
   953  	print("decl \"%s\": C=%s [B=%d:O=%d] T=%T\n",
   954  		s->name, cnames[s->class], s->block, s->offset, s->type);
   955  }
   956  
   957  Decl*
   958  push(void)
   959  {
   960  	Decl *d;
   961  
   962  	d = alloc(sizeof(*d));
   963  	d->link = dclstack;
   964  	dclstack = d;
   965  	return d;
   966  }
   967  
   968  Decl*
   969  push1(Sym *s)
   970  {
   971  	Decl *d;
   972  
   973  	d = push();
   974  	d->sym = s;
   975  	d->val = DAUTO;
   976  	d->type = s->type;
   977  	d->class = s->class;
   978  	d->offset = s->offset;
   979  	d->block = s->block;
   980  	d->varlineno = s->varlineno;
   981  	d->aused = s->aused;
   982  	return d;
   983  }
   984  
   985  int
   986  sametype(Type *t1, Type *t2)
   987  {
   988  
   989  	if(t1 == t2)
   990  		return 1;
   991  	return rsametype(t1, t2, 5, 1);
   992  }
   993  
   994  int
   995  rsametype(Type *t1, Type *t2, int n, int f)
   996  {
   997  	int et;
   998  
   999  	n--;
  1000  	for(;;) {
  1001  		if(t1 == t2)
  1002  			return 1;
  1003  		if(t1 == T || t2 == T)
  1004  			return 0;
  1005  		if(n <= 0)
  1006  			return 1;
  1007  		et = t1->etype;
  1008  		if(et != t2->etype)
  1009  			return 0;
  1010  		if(et == TFUNC) {
  1011  			if(!rsametype(t1->link, t2->link, n, 0))
  1012  				return 0;
  1013  			t1 = t1->down;
  1014  			t2 = t2->down;
  1015  			while(t1 != T && t2 != T) {
  1016  				if(t1->etype == TOLD) {
  1017  					t1 = t1->down;
  1018  					continue;
  1019  				}
  1020  				if(t2->etype == TOLD) {
  1021  					t2 = t2->down;
  1022  					continue;
  1023  				}
  1024  				while(t1 != T || t2 != T) {
  1025  					if(!rsametype(t1, t2, n, 0))
  1026  						return 0;
  1027  					t1 = t1->down;
  1028  					t2 = t2->down;
  1029  				}
  1030  				break;
  1031  			}
  1032  			return 1;
  1033  		}
  1034  		if(et == TARRAY)
  1035  			if(t1->width != t2->width && t1->width != 0 && t2->width != 0)
  1036  				return 0;
  1037  		if(typesu[et]) {
  1038  			if(t1->link == T)
  1039  				snap(t1);
  1040  			if(t2->link == T)
  1041  				snap(t2);
  1042  			t1 = t1->link;
  1043  			t2 = t2->link;
  1044  			for(;;) {
  1045  				if(t1 == t2)
  1046  					return 1;
  1047  				if(!rsametype(t1, t2, n, 0))
  1048  					return 0;
  1049  				t1 = t1->down;
  1050  				t2 = t2->down;
  1051  			}
  1052  		}
  1053  		t1 = t1->link;
  1054  		t2 = t2->link;
  1055  		if((f || !debug['V']) && et == TIND) {
  1056  			if(t1 != T && t1->etype == TVOID)
  1057  				return 1;
  1058  			if(t2 != T && t2->etype == TVOID)
  1059  				return 1;
  1060  		}
  1061  	}
  1062  }
  1063  
  1064  typedef struct Typetab Typetab;
  1065  
  1066  struct Typetab{
  1067  	int n;
  1068  	Type **a;
  1069  };
  1070  
  1071  static int
  1072  sigind(Type *t, Typetab *tt)
  1073  {
  1074  	int n;
  1075  	Type **a, **na, **p, **e;
  1076  
  1077  	n = tt->n;
  1078  	a = tt->a;
  1079  	e = a+n;
  1080  	/* linear search seems ok */
  1081  	for(p = a ; p < e; p++)
  1082  		if(sametype(*p, t))
  1083  			return p-a;
  1084  	if((n&15) == 0){
  1085  		na = malloc((n+16)*sizeof(Type*));
  1086  		if(na == nil) {
  1087  			print("%s: out of memory", argv0);
  1088  			errorexit();
  1089  		}
  1090  		memmove(na, a, n*sizeof(Type*));
  1091  		free(a);
  1092  		a = tt->a = na;
  1093  	}
  1094  	a[tt->n++] = t;
  1095  	return -1;
  1096  }
  1097  
  1098  static uint32
  1099  signat(Type *t, Typetab *tt)
  1100  {
  1101  	int i;
  1102  	Type *t1;
  1103  	int32 s;
  1104  
  1105  	s = 0;
  1106  	for(; t; t=t->link) {
  1107  		s = s*thash1 + thash[t->etype];
  1108  		if(t->garb&GINCOMPLETE)
  1109  			return s;
  1110  		switch(t->etype) {
  1111  		default:
  1112  			return s;
  1113  		case TARRAY:
  1114  			s = s*thash2 + 0;	/* was t->width */
  1115  			break;
  1116  		case TFUNC:
  1117  			for(t1=t->down; t1; t1=t1->down)
  1118  				s = s*thash3 + signat(t1, tt);
  1119  			break;
  1120  		case TSTRUCT:
  1121  		case TUNION:
  1122  			if((i = sigind(t, tt)) >= 0){
  1123  				s = s*thash2 + i;
  1124  				return s;
  1125  			}
  1126  			for(t1=t->link; t1; t1=t1->down)
  1127  				s = s*thash3 + signat(t1, tt);
  1128  			return s;
  1129  		case TIND:
  1130  			break;
  1131  		}
  1132  	}
  1133  	return s;
  1134  }
  1135  
  1136  uint32
  1137  signature(Type *t)
  1138  {
  1139  	uint32 s;
  1140  	Typetab tt;
  1141  
  1142  	tt.n = 0;
  1143  	tt.a = nil;
  1144  	s = signat(t, &tt);
  1145  	free(tt.a);
  1146  	return s;
  1147  }
  1148  
  1149  uint32
  1150  sign(Sym *s)
  1151  {
  1152  	uint32 v;
  1153  	Type *t;
  1154  
  1155  	if(s->sig == SIGINTERN)
  1156  		return SIGNINTERN;
  1157  	if((t = s->type) == T)
  1158  		return 0;
  1159  	v = signature(t);
  1160  	if(v == 0)
  1161  		v = SIGNINTERN;
  1162  	return v;
  1163  }
  1164  
  1165  void
  1166  snap(Type *t)
  1167  {
  1168  	if(typesu[t->etype])
  1169  	if(t->link == T && t->tag && t->tag->suetag) {
  1170  		t->link = t->tag->suetag->link;
  1171  		t->width = t->tag->suetag->width;
  1172  	}
  1173  }
  1174  
  1175  Type*
  1176  dotag(Sym *s, int et, int bn)
  1177  {
  1178  	Decl *d;
  1179  
  1180  	if(bn != 0 && bn != s->sueblock) {
  1181  		d = push();
  1182  		d->sym = s;
  1183  		d->val = DSUE;
  1184  		d->type = s->suetag;
  1185  		d->block = s->sueblock;
  1186  		s->suetag = T;
  1187  	}
  1188  	if(s->suetag == T) {
  1189  		s->suetag = typ(et, T);
  1190  		s->sueblock = autobn;
  1191  	}
  1192  	if(s->suetag->etype != et)
  1193  		diag(Z, "tag used for more than one type: %s",
  1194  			s->name);
  1195  	if(s->suetag->tag == S)
  1196  		s->suetag->tag = s;
  1197  	return s->suetag;
  1198  }
  1199  
  1200  Node*
  1201  dcllabel(Sym *s, int f)
  1202  {
  1203  	Decl *d, d1;
  1204  	Node *n;
  1205  
  1206  	n = s->label;
  1207  	if(n != Z) {
  1208  		if(f) {
  1209  			if(n->complex)
  1210  				diag(Z, "label reused: %s", s->name);
  1211  			n->complex = 1;	// declared
  1212  		} else
  1213  			n->addable = 1;	// used
  1214  		return n;
  1215  	}
  1216  
  1217  	d = push();
  1218  	d->sym = s;
  1219  	d->val = DLABEL;
  1220  	dclstack = d->link;
  1221  
  1222  	d1 = *firstdcl;
  1223  	*firstdcl = *d;
  1224  	*d = d1;
  1225  
  1226  	firstdcl->link = d;
  1227  	firstdcl = d;
  1228  
  1229  	n = new(OXXX, Z, Z);
  1230  	n->sym = s;
  1231  	n->complex = f;
  1232  	n->addable = !f;
  1233  	s->label = n;
  1234  
  1235  	if(debug['d'])
  1236  		dbgdecl(s);
  1237  	return n;
  1238  }
  1239  
  1240  Type*
  1241  paramconv(Type *t, int f)
  1242  {
  1243  
  1244  	switch(t->etype) {
  1245  	case TUNION:
  1246  	case TSTRUCT:
  1247  		if(t->width <= 0)
  1248  			diag(Z, "incomplete structure: %s", t->tag->name);
  1249  		break;
  1250  
  1251  	case TARRAY:
  1252  		t = typ(TIND, t->link);
  1253  		t->width = types[TIND]->width;
  1254  		break;
  1255  
  1256  	case TFUNC:
  1257  		t = typ(TIND, t);
  1258  		t->width = types[TIND]->width;
  1259  		break;
  1260  
  1261  	case TFLOAT:
  1262  		if(!f)
  1263  			t = types[TDOUBLE];
  1264  		break;
  1265  
  1266  	case TCHAR:
  1267  	case TSHORT:
  1268  		if(!f)
  1269  			t = types[TINT];
  1270  		break;
  1271  
  1272  	case TUCHAR:
  1273  	case TUSHORT:
  1274  		if(!f)
  1275  			t = types[TUINT];
  1276  		break;
  1277  	}
  1278  	return t;
  1279  }
  1280  
  1281  void
  1282  adecl(int c, Type *t, Sym *s)
  1283  {
  1284  
  1285  	if(c == CSTATIC)
  1286  		c = CLOCAL;
  1287  	if(t->etype == TFUNC) {
  1288  		if(c == CXXX)
  1289  			c = CEXTERN;
  1290  		if(c == CLOCAL)
  1291  			c = CSTATIC;
  1292  		if(c == CAUTO || c == CEXREG)
  1293  			diag(Z, "function cannot be %s %s", cnames[c], s->name);
  1294  	}
  1295  	if(c == CXXX)
  1296  		c = CAUTO;
  1297  	if(s) {
  1298  		if(s->class == CSTATIC)
  1299  			if(c == CEXTERN || c == CGLOBL) {
  1300  				warn(Z, "just say static: %s", s->name);
  1301  				c = CSTATIC;
  1302  			}
  1303  		if(s->class == CAUTO || s->class == CPARAM || s->class == CLOCAL)
  1304  		if(s->block == autobn)
  1305  			diag(Z, "auto redeclaration of: %s", s->name);
  1306  		if(c != CPARAM)
  1307  			push1(s);
  1308  		s->block = autobn;
  1309  		s->offset = 0;
  1310  		s->type = t;
  1311  		s->class = c;
  1312  		s->aused = 0;
  1313  	}
  1314  	switch(c) {
  1315  	case CAUTO:
  1316  		autoffset = align(autoffset, t, Aaut3, nil);
  1317  		stkoff = maxround(stkoff, autoffset);
  1318  		s->offset = -autoffset;
  1319  		break;
  1320  
  1321  	case CPARAM:
  1322  		if(autoffset == 0) {
  1323  			firstarg = s;
  1324  			firstargtype = t;
  1325  		}
  1326  		autoffset = align(autoffset, t, Aarg1, nil);
  1327  		if(s)
  1328  			s->offset = autoffset;
  1329  		autoffset = align(autoffset, t, Aarg2, nil);
  1330  		break;
  1331  	}
  1332  }
  1333  
  1334  void
  1335  pdecl(int c, Type *t, Sym *s)
  1336  {
  1337  	if(s && s->offset != -1) {
  1338  		diag(Z, "not a parameter: %s", s->name);
  1339  		return;
  1340  	}
  1341  	t = paramconv(t, c==CPARAM);
  1342  	if(c == CXXX)
  1343  		c = CPARAM;
  1344  	if(c != CPARAM) {
  1345  		diag(Z, "parameter cannot have class: %s", s->name);
  1346  		c = CPARAM;
  1347  	}
  1348  	adecl(c, t, s);
  1349  }
  1350  
  1351  void
  1352  xdecl(int c, Type *t, Sym *s)
  1353  {
  1354  	int32 o;
  1355  
  1356  	o = 0;
  1357  	switch(c) {
  1358  	case CEXREG:
  1359  		o = exreg(t);
  1360  		if(o == 0)
  1361  			c = CEXTERN;
  1362  		if(s->class == CGLOBL)
  1363  			c = CGLOBL;
  1364  		break;
  1365  
  1366  	case CEXTERN:
  1367  		if(s->class == CGLOBL)
  1368  			c = CGLOBL;
  1369  		break;
  1370  
  1371  	case CXXX:
  1372  		c = CGLOBL;
  1373  		if(s->class == CEXTERN)
  1374  			s->class = CGLOBL;
  1375  		break;
  1376  
  1377  	case CAUTO:
  1378  		diag(Z, "overspecified class: %s %s %s", s->name, cnames[c], cnames[s->class]);
  1379  		c = CEXTERN;
  1380  		break;
  1381  
  1382  	case CTYPESTR:
  1383  		if(!typesuv[t->etype]) {
  1384  			diag(Z, "typestr must be struct/union: %s", s->name);
  1385  			break;
  1386  		}
  1387  		dclfunct(t, s);
  1388  		break;
  1389  	}
  1390  
  1391  	if(s->class == CSTATIC)
  1392  		if(c == CEXTERN || c == CGLOBL) {
  1393  			warn(Z, "overspecified class: %s %s %s", s->name, cnames[c], cnames[s->class]);
  1394  			c = CSTATIC;
  1395  		}
  1396  	if(s->type != T)
  1397  		if(s->class != c || !sametype(t, s->type) || t->etype == TENUM) {
  1398  			diag(Z, "external redeclaration of: %s", s->name);
  1399  			Bprint(&diagbuf, "	%s %T %L\n", cnames[c], t, nearln);
  1400  			Bprint(&diagbuf, "	%s %T %L\n", cnames[s->class], s->type, s->varlineno);
  1401  		}
  1402  	tmerge(t, s);
  1403  	s->type = t;
  1404  	s->class = c;
  1405  	s->block = 0;
  1406  	s->offset = o;
  1407  }
  1408  
  1409  void
  1410  tmerge(Type *t1, Sym *s)
  1411  {
  1412  	Type *ta, *tb, *t2;
  1413  
  1414  	t2 = s->type;
  1415  	for(;;) {
  1416  		if(t1 == T || t2 == T || t1 == t2)
  1417  			break;
  1418  		if(t1->etype != t2->etype)
  1419  			break;
  1420  		switch(t1->etype) {
  1421  		case TFUNC:
  1422  			ta = t1->down;
  1423  			tb = t2->down;
  1424  			if(ta == T) {
  1425  				t1->down = tb;
  1426  				break;
  1427  			}
  1428  			if(tb == T)
  1429  				break;
  1430  			while(ta != T && tb != T) {
  1431  				if(ta == tb)
  1432  					break;
  1433  				/* ignore old-style flag */
  1434  				if(ta->etype == TOLD) {
  1435  					ta = ta->down;
  1436  					continue;
  1437  				}
  1438  				if(tb->etype == TOLD) {
  1439  					tb = tb->down;
  1440  					continue;
  1441  				}
  1442  				/* checking terminated by ... */
  1443  				if(ta->etype == TDOT && tb->etype == TDOT) {
  1444  					ta = T;
  1445  					tb = T;
  1446  					break;
  1447  				}
  1448  				if(!sametype(ta, tb))
  1449  					break;
  1450  				ta = ta->down;
  1451  				tb = tb->down;
  1452  			}
  1453  			if(ta != tb)
  1454  				diag(Z, "function inconsistently declared: %s", s->name);
  1455  
  1456  			/* take new-style over old-style */
  1457  			ta = t1->down;
  1458  			tb = t2->down;
  1459  			if(ta != T && ta->etype == TOLD)
  1460  				if(tb != T && tb->etype != TOLD)
  1461  					t1->down = tb;
  1462  			break;
  1463  
  1464  		case TARRAY:
  1465  			/* should we check array size change? */
  1466  			if(t2->width > t1->width)
  1467  				t1->width = t2->width;
  1468  			break;
  1469  
  1470  		case TUNION:
  1471  		case TSTRUCT:
  1472  			return;
  1473  		}
  1474  		t1 = t1->link;
  1475  		t2 = t2->link;
  1476  	}
  1477  }
  1478  
  1479  void
  1480  edecl(int c, Type *t, Sym *s)
  1481  {
  1482  	Type *t1;
  1483  
  1484  	if(s == S) {
  1485  		if(!typesu[t->etype])
  1486  			diag(Z, "unnamed structure element must be struct/union");
  1487  		if(c != CXXX)
  1488  			diag(Z, "unnamed structure element cannot have class");
  1489  	} else
  1490  		if(c != CXXX)
  1491  			diag(Z, "structure element cannot have class: %s", s->name);
  1492  	t1 = t;
  1493  	t = copytyp(t1);
  1494  	t->sym = s;
  1495  	t->down = T;
  1496  	if(lastfield) {
  1497  		t->shift = lastbit - lastfield;
  1498  		t->nbits = lastfield;
  1499  		if(firstbit)
  1500  			t->shift = -t->shift;
  1501  		if(typeu[t->etype])
  1502  			t->etype = tufield->etype;
  1503  		else
  1504  			t->etype = tfield->etype;
  1505  	}
  1506  	if(strf == T)
  1507  		strf = t;
  1508  	else
  1509  		strl->down = t;
  1510  	strl = t;
  1511  }
  1512  
  1513  /*
  1514   * this routine is very suspect.
  1515   * ansi requires the enum type to
  1516   * be represented as an 'int'
  1517   * this means that 0x81234567
  1518   * would be illegal. this routine
  1519   * makes signed and unsigned go
  1520   * to unsigned.
  1521   */
  1522  Type*
  1523  maxtype(Type *t1, Type *t2)
  1524  {
  1525  
  1526  	if(t1 == T)
  1527  		return t2;
  1528  	if(t2 == T)
  1529  		return t1;
  1530  	if(t1->etype > t2->etype)
  1531  		return t1;
  1532  	return t2;
  1533  }
  1534  
  1535  void
  1536  doenum(Sym *s, Node *n)
  1537  {
  1538  
  1539  	if(n) {
  1540  		complex(n);
  1541  		if(n->op != OCONST) {
  1542  			diag(n, "enum not a constant: %s", s->name);
  1543  			return;
  1544  		}
  1545  		en.cenum = n->type;
  1546  		en.tenum = maxtype(en.cenum, en.tenum);
  1547  
  1548  		if(!typefd[en.cenum->etype])
  1549  			en.lastenum = n->vconst;
  1550  		else
  1551  			en.floatenum = n->fconst;
  1552  	}
  1553  	if(dclstack)
  1554  		push1(s);
  1555  	xdecl(CXXX, types[TENUM], s);
  1556  
  1557  	if(en.cenum == T) {
  1558  		en.tenum = types[TINT];
  1559  		en.cenum = types[TINT];
  1560  		en.lastenum = 0;
  1561  	}
  1562  	s->tenum = en.cenum;
  1563  
  1564  	if(!typefd[s->tenum->etype]) {
  1565  		s->vconst = convvtox(en.lastenum, s->tenum->etype);
  1566  		en.lastenum++;
  1567  	} else {
  1568  		s->fconst = en.floatenum;
  1569  		en.floatenum++;
  1570  	}
  1571  
  1572  	if(debug['d'])
  1573  		dbgdecl(s);
  1574  	acidvar(s);
  1575  	godefvar(s);
  1576  }
  1577  
  1578  void
  1579  symadjust(Sym *s, Node *n, int32 del)
  1580  {
  1581  
  1582  	switch(n->op) {
  1583  	default:
  1584  		if(n->left)
  1585  			symadjust(s, n->left, del);
  1586  		if(n->right)
  1587  			symadjust(s, n->right, del);
  1588  		return;
  1589  
  1590  	case ONAME:
  1591  		if(n->sym == s)
  1592  			n->xoffset -= del;
  1593  		return;
  1594  
  1595  	case OCONST:
  1596  	case OSTRING:
  1597  	case OLSTRING:
  1598  	case OINDREG:
  1599  	case OREGISTER:
  1600  		return;
  1601  	}
  1602  }
  1603  
  1604  Node*
  1605  contig(Sym *s, Node *n, int32 v)
  1606  {
  1607  	Node *p, *r, *q, *m;
  1608  	int32 w;
  1609  	Type *zt;
  1610  
  1611  	if(debug['i']) {
  1612  		print("contig v = %d; s = %s\n", v, s->name);
  1613  		prtree(n, "doinit value");
  1614  	}
  1615  
  1616  	if(n == Z)
  1617  		goto no;
  1618  	w = s->type->width;
  1619  
  1620  	/*
  1621  	 * nightmare: an automatic array whose size
  1622  	 * increases when it is initialized
  1623  	 */
  1624  	if(v != w) {
  1625  		if(v != 0)
  1626  			diag(n, "automatic adjustable array: %s", s->name);
  1627  		v = s->offset;
  1628  		autoffset = align(autoffset, s->type, Aaut3, nil);
  1629  		s->offset = -autoffset;
  1630  		stkoff = maxround(stkoff, autoffset);
  1631  		symadjust(s, n, v - s->offset);
  1632  	}
  1633  	if(w <= ewidth[TIND])
  1634  		goto no;
  1635  	if(n->op == OAS)
  1636  		diag(Z, "oops in contig");
  1637  /*ZZZ this appears incorrect
  1638  need to check if the list completely covers the data.
  1639  if not, bail
  1640   */
  1641  	if(n->op == OLIST)
  1642  		goto no;
  1643  	if(n->op == OASI)
  1644  		if(n->left->type)
  1645  		if(n->left->type->width == w)
  1646  			goto no;
  1647  	while(w & (ewidth[TIND]-1))
  1648  		w++;
  1649  /*
  1650   * insert the following code, where long becomes vlong if pointers are fat
  1651   *
  1652  	*(long**)&X = (long*)((char*)X + sizeof(X));
  1653  	do {
  1654  		*(long**)&X -= 1;
  1655  		**(long**)&X = 0;
  1656  	} while(*(long**)&X);
  1657   */
  1658  
  1659  	for(q=n; q->op != ONAME; q=q->left)
  1660  		;
  1661  
  1662  	zt = ewidth[TIND] > ewidth[TLONG]? types[TVLONG]: types[TLONG];
  1663  
  1664  	p = new(ONAME, Z, Z);
  1665  	*p = *q;
  1666  	p->type = typ(TIND, zt);
  1667  	p->xoffset = s->offset;
  1668  
  1669  	r = new(ONAME, Z, Z);
  1670  	*r = *p;
  1671  	r = new(OPOSTDEC, r, Z);
  1672  
  1673  	q = new(ONAME, Z, Z);
  1674  	*q = *p;
  1675  	q = new(OIND, q, Z);
  1676  
  1677  	m = new(OCONST, Z, Z);
  1678  	m->vconst = 0;
  1679  	m->type = zt;
  1680  
  1681  	q = new(OAS, q, m);
  1682  
  1683  	r = new(OLIST, r, q);
  1684  
  1685  	q = new(ONAME, Z, Z);
  1686  	*q = *p;
  1687  	r = new(ODWHILE, q, r);
  1688  
  1689  	q = new(ONAME, Z, Z);
  1690  	*q = *p;
  1691  	q->type = q->type->link;
  1692  	q->xoffset += w;
  1693  	q = new(OADDR, q, 0);
  1694  
  1695  	q = new(OASI, p, q);
  1696  	r = new(OLIST, q, r);
  1697  
  1698  	n = new(OLIST, r, n);
  1699  
  1700  no:
  1701  	return n;
  1702  }