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