1File: DECL.C                                                              Page       1
     1   /*
     2   	Copyright 1982
     3   	Alcyon Corporation
     4   	8716 Production Ave.
     5   	San Diego, Ca.  92121
     6   */
     7    
     8   #include "parser.h"
     9   #define	DTSIZE	077					/*data size in bytes*/
    10   #define	DREG	0100				/*data loadable into D-register?*/
    11    
    12   char dinfo[] {
    13   	0,								/*TYPELESS=0*/
    14   	1|DREG,							/*CHAR=1*/
    15   	2|DREG,							/*SHORT=2*/
    16   	2|DREG,							/*INT=3*/
    17   	4|DREG,							/*LONG=4*/
    18   	1|DREG,							/*UCHAR=5*/
    19   	2|DREG,							/*USHORT=6*/
    20   	2|DREG,							/*UNSIGNED=7*/
    21   	4|DREG,							/*ULONG=8*/
    22   	4|DREG,							/*FLOAT=9[vlh]*/
    23   	4|DREG,							/*DOUBLE=10[vlh]*/
    24   	0,								/*STRUCT=11*/
    25   	0,								/*FRSTRUCT=12*/
    26   	0,								/*LLABEL=13*/
    27   	0,								/*INVALID=14*/
    28   	0,								/*INVALID=15*/
    29   };
    30    
    31   char aregtab[] { AREG5, AREG4, AREG3, 0 };
    32   char dregtab[] { DREG7, DREG6, DREG5, DREG4, DREG3, 0 };
    33   int inittype;
    34    
    35   /*
    36    * doextdef - external definition syntax
    37    *		This is fairly complicated since you do not know if you are
    38    *		parsing a external function declaration or a real function
    39    *		until after you've already scanned the argument list for the
    40    *		function.  Basically you start off scanning an external declaration
    41    *		or function in the same way by collecting attributes, scanning
    42    *		the declarator, then scanning the function arguments if a function.
    43    *		At that point you look at the next token and if its a '{', keyword
    44    *		proceed accordingly.
    45    *		The C Syntax handled by this routine is (roughly):
    46    *			external_definition:
    47    *					function_definition
    48    *					data_definition
    49    *			function_definition:
    50    *					type_specifier function_declarator function_body
    51    *			function_declarator:
    52    *					declarator ( parameter_list )
    53    *			data_definition:
    54    *					EXTERNAL type_specifier init_declarator_list ;
    55    *					STATIC type_specifier init_declarator_list ;
    56    */
    57   doextdef()							/* returns 0 for EOF or 1*/
    58   {
    59   	register struct symbol *sp;
1File: DECL.C                                                              Page       2
    60   	register int dflag;
    61   	int sc, type;
    62   	long size;
    63    
    64   	if(!next(SEMI)) {
    65   		opap = exprp = exprarea;
    66   		sc = EXTERNAL;
    67   		type = (xflag?LONG:INT);
    68   		dflag = gettype(&sc,&type,&size);
    69   		if(type==STRUCT)	/* deal with forward ref structures */
    70   			chksyms();
    71   		while( dodecl(sc,type,0,size), (sp=dsp) != 0 ) {
    72   			if( !dflag && notfunction(sp->s_type) ) {
    73   				synerr("external definition syntax");
    74   				return;
    75   			}
    76   			if( !stypedef(sp) && sc != STATIC )
    77   				if (notfunction(sp->s_type))	/*[vlh] .globl ext. vars*/
    78   					outextdef(sp->s_symbol);
    79   			if( notfunction(sp->s_type) ) {	/*not function, check init*/
    80   				if( !stypedef(sp) ) {
    81   					doinit(sp);
    82   					if (sc == STATIC)
    83   						chksyms();
    84   				}
    85   			}
    86   			else if( peek(RESWORD) || peek(LCURBR) ||
    87   					(peek(SYMBOL) && stypedef(csp)) ) {
    88   				if(!stypedef(sp) && sc!=STATIC)	/*[vlh] .globl local proc*/
    89   					outextdef(sp->s_symbol);
    90   				funcbody(sp);
    91   				return;
    92   			}
    93   			dsp = 0;
    94   			if( !next(COMMA) )
    95   				break;
    96   		}
    97   		if( gettok() != SEMI )
    98   			synerr("external definition syntax");
    99   	}
   100   }
   101    
   102   /*
   103    * gettype - get attribute types in attribute list
   104    *		Handles single word keywords, such as int, char, etc. and also
   105    *		handles the declarations of structures and unions.
   106    */
   107   gettype(defsc,deftype,size)			/* returns 0 for no type, 1 otherwise*/
   108   int *defsc;							/* default storage class*/
   109   int *deftype;						/* default data type*/
   110   long *size;							/* size of data element 3.4 int=>long*/
   111   {
   112   	register int dtype, sc;
   113   	register int sflag, uflag, lflag, decflag;
   114   	register int token, stdflag, sbits;
   115   	long tsize;
   116   	register struct symbol *sp, *parent;
   117    
   118   	tdp = 0; tdflag = uflag = decflag = lflag = sflag = 0; tsize = 0L;
1File: DECL.C                                                              Page       3
   119   	dtype = TYPELESS;
   120   	sc = *defsc;
   121   	for( ; ; decflag++ ) {
   122   		if( (token=gettok()) == SYMBOL && stypedef(csp) ) {
   123   			dtype = 0;
   124   			tdp = csp;
   125   			continue;
   126   		}
   127   		if( token != RESWORD )
   128   			break;
   129   		switch( cvalue ) {
   130    
   131   		case R_TYPEDEF:
   132   			if( tdflag )
   133   				error("invalid typedef statement");
   134   			tdflag++;
   135   			continue;
   136    
   137   		case R_STATIC:
   138   			if( sc && sc != STATIC && sc != EXTERNAL )
   139   				error("invalid storage class");
   140   			sc = STATIC;
   141   			continue;
   142    
   143   		case R_AUTO:
   144   			if( sc && sc != AUTO )
   145   				error("invalid storage class");
   146   			sc = AUTO;
   147   			continue;
   148    
   149   		case R_EXTERNAL:
   150   			if( sc && sc != EXTERNAL )
   151   				error("invalid storage class");
   152   			sc = EXTERNAL;
   153   			continue;
   154   	
   155   		case R_REGISTER:
   156   			if( sc && sc != REGISTER && sc != PDECLIST )
   157   				error("invalid register specification");
   158   			sc = REGISTER;
   159   			continue;
   160   	
   161   		case R_LONG:
   162   			lflag++;
   163   			continue;
   164    
   165   		case R_SHORT:
   166   			sflag++;
   167   			continue;
   168    
   169   		case R_UNSIGNED:
   170   			uflag++;
   171   			continue;
   172    
   173   		case R_STRUCT:
   174   			cvalue = STRUCT;
   175   		case R_UNION:
   176   			stdflag = tdflag;
   177   			tdflag = 0; sp = 0;
1File: DECL.C                                                              Page       4
   178   			token = cvalue;
   179   			smember++;
   180   			if( next(SYMBOL) ) {	/*struct [symbol] { ... }*/
   181   				sp = csp;
   182   				parent = csp;
   183   				strucptr[smember+instruct] = sp;
   184   				if( !sp->s_sc ) {
   185   					sp->s_attrib =| SDEFINED;
   186   					if(!infunc)
   187   						sp->s_attrib =| SGLOBAL;
   188   					sp->s_sc = STRPROTO;
   189   					sp->s_type = STRUCT;
   190   					sp->s_ssp = dalloc(0L);
   191   				}
   192   				if( sp->s_sc != STRPROTO )
   193   					error("redeclaration: %.8s",sp->s_symbol);
   194   			}
   195   			else parent = 0;
   196   			smember = 0;
   197   			if( next(LCURBR) ) {
   198   				instruct++;
   199   				strucptr[smember+instruct] = sp;
   200   				sbits = boffset;
   201   				boffset = 0;
   202   				tsize = dlist(token==STRUCT?STELCL:UNELCL);
   203   				boffset = sbits;
   204   				if(!next(RCURBR))
   205   					synerr("structure declaration syntax");
   206   				else if( sp ) {
   207   					if( dtab[sp->s_ssp] )
   208   						error("redeclaration: %.8s",sp->s_symbol);
   209   					dtab[sp->s_ssp] = tsize;
   210   				}
   211   				instruct--;
   212   			}
   213   			else if( !sp )
   214   				error("no structure name");
   215   			else if( sp->s_sc != STRPROTO )
   216   				error("invalid structure prototype: %.8s",sp->s_symbol);
   217   			else if( !dtab[sp->s_ssp] ) {	/* FRSTRUCT */
   218   				token = FRSTRUCT;
   219   				if( ++frstp >= NFRSTR )
   220   					ferror("structure table overflow");
   221   				frstab[frstp] = sp;
   222   			}
   223   			else
   224   				tsize = dtab[sp->s_ssp];
   225   			tdflag = stdflag;
   226   			if( dtype != TYPELESS )
   227   				error("invalid type declaration");
   228   			dtype = (token == R_UNION) ? STRUCT : token;
   229   			continue;
   230    
   231   		case R_INT:
   232   			if( dtype != TYPELESS )
   233   				error("invalid type declaration");
   234   			dtype = INT;
   235   			continue;
   236    
1File: DECL.C                                                              Page       5
   237   		case R_CHAR:
   238   			if( dtype != TYPELESS )
   239   				error("invalid type declaration");
   240   			dtype = CHAR;
   241   			continue;
   242    
   243   		case R_FLOAT:	/*[vlh] ver. 3.4*/
   244   		case R_DOUBLE:
   245   			if( dtype != TYPELESS )
   246   				error("invalid type declaration");
   247   			dtype = FLOAT;
   248   			continue;
   249   		}
   250   		break;
   251   	}
   252   	pbtok(token);
   253   	if( dtype == TYPELESS )
   254   		dtype = INT;
   255   	if(!sc)
   256   		sc = AUTO;
   257   	if( lflag ) {					/*allow: long float, long int*/
   258   		if( dtype == INT )
   259   			dtype = LONG;
   260   /*		else if( dtype == FLOAT )	*/
   261   /*			dtype = DOUBLE;			*/
   262   		else
   263   			error("invalid long declaration");
   264   	}
   265   	if( sflag ) {
   266   		if( dtype != INT )
   267   			error("invalid short declaration");
   268   	}
   269   	if( uflag ) {
   270   		if( dtype != INT )			/*allow: unsigned int*/
   271   			error("invalid unsigned declaration");
   272   		else
   273   			dtype = UNSIGNED;
   274   	}
   275   	if( !sflag && xflag && dtype == INT )
   276   		dtype = LONG;
   277   	*defsc = sc;
   278   	*deftype = dtype;
   279   	*size = tsize;
   280   	if (dtype == STRUCT || dtype == FRSTRUCT)
   281   		csp->s_struc = parent;
   282   	return(decflag);
   283   }
   284    
   285   /*
   286    * dodecl - process a single declarator
   287    *		This does all the grubby handling of a single declarator given
   288    *		the attributes for the declarator.  Handles typedef attributes
   289    *		adjusts offsets for structure elements, allocates register
   290    *		variables, etc.
   291    */
   292   long								/* [vlh] 3.4 int => long */
   293   dodecl(sc,type,offset,size)			/* returns size of declarator*/
   294   int sc;								/* storage class*/
   295   int type;							/* data type*/
1File: DECL.C                                                              Page       6
   296   int offset;							/* offset if in structure or union*/
   297   long size;							/* size of single data item 3.4 i=> l*/
   298   {
   299   	register struct symbol *sp;
   300   	register int redecf, stype, dtype, i, j;
   301    
   302   	if( peek(SEMI) || peek(RPAREN) )
   303   		return(0);
   304   	if( instruct && next(COLON) ) {	/*handle bit filler field*/
   305   		if(!(i=cexpr()))
   306   			size = salign(INT,offset);
   307   		else
   308   			size = falign(type,i);
   309   	}
   310   	else if( (type=|declarator(0)) >= 0 && (sp=dsp) != 0 ) {
   311   		if( tdp )					/*typedef name in declaration*/
   312   			type = addtdtype(tdp,type,sp->s_dp,&(sp->s_ssp));
   313   		else if( btype(type) == STRUCT ) {
   314   			if( size )
   315   				sp->s_ssp = dalloc(size);
   316   			else
   317   				error("invalid structure declaration: %.8s",sp->s_symbol);
   318   		}
   319   		else if( btype(type) == FRSTRUCT )
   320   			sp->s_ssp = frstp;
   321   		redecf = 0;
   322   		switch( sp->s_sc ) {		/*check for redeclarations.*/
   323    
   324   		case 0:
   325   			break;
   326    
   327   		case PARMLIST:
   328   			if( sc != PDECLIST && sc != REGISTER )
   329   				goto redec;
   330   			break;
   331    
   332   		case BFIELDCL:
   333   			if( sc != STELCL && sc != UNELCL )
   334   				goto redec;
   335   			break;
   336    
   337   		case STELCL:
   338   		case UNELCL:
   339   			redecf++;
   340   			break;	/* [vlh] get rid of redecf entirely ?? */
   341    
   342   		case EXTERNAL:
   343   			if (sp->s_type == type) {
   344   				if (sc == sp->s_sc) break;
   345   				if (sc == AUTO && suptype(type) == FUNCTION) {
   346   					sc = EXTERNAL;
   347   					break;
   348   				}
   349   			}
   350   		default:
   351   redec:
   352   			error("redeclaration: %.8s",sp->s_symbol);
   353   			return(size);
   354   		}
1File: DECL.C                                                              Page       7
   355   		sp->s_type = type;
   356   		dtype = suptype(type);
   357   		type = btype(type);
   358   		if( tdflag )				/*we are declaring typedef?*/
   359   			sp->s_attrib =| STYPEDEF;
   360   		if( instruct ) {
   361   			if( next(COLON) ) {		/*handle bit field*/
   362   				sc = BFIELDCL;
   363   				i = cexpr();
   364   				j = (boffset<<8)|i;
   365   				if( redecf && sp->s_dp != j )	/* ??? */
   366   					goto redec;
   367   				sp->s_dp = j;
   368   				size = j = falign(type,i);
   369   			}
   370   			else
   371   				size = dsize(sp->s_type,sp->s_dp,sp->s_ssp) +
   372   						(j=salign(type,offset));
   373   			offset =+ j;
   374   /*			if( redecf && sp->s_offset != offset )
   375   				goto redec;	*/	/* [vlh] */
   376   			sp->s_offset = offset;
   377   		}
   378   		if( dtype == FUNCTION ) {
   379   			if( sc != AUTO && sc != EXTERNAL && sc != STATIC )
   380   				error("illegal function declaration");
   381   			if( sc != STATIC )
   382   				sc = EXTERNAL;
   383   		}
   384   		else if( sc == REGISTER ) {
   385   			if( !dtype ) {
   386   				if( !(dinfo[type]&DREG) ) {	/* ignore reg specification */
   387   /*					error("illegal register specification"); */
   388   					sc = AUTO;
   389   				}
   390   				else if( !dregtab[ndregs] )
   391   					sc = AUTO;
   392   				else
   393   					sp->s_offset = dregtab[ndregs++];
   394   			}
   395   			else if( dtype != POINTER ) {
   396   				error("illegal register specification");
   397   				sc = AUTO;			/*no more regs, make it auto*/
   398   			}
   399   			else if( !aregtab[naregs] )
   400   				sc = AUTO;
   401   			else
   402   				sp->s_offset = aregtab[naregs++];
   403   		}
   404   		if( sc == AUTO ) {
   405   			localsize =+ walign(dsize(sp->s_type,sp->s_dp,sp->s_ssp));
   406   			sp->s_offset = -localsize;
   407   		}
   408   		else if( sc == STATIC )
   409   			sp->s_offset = nextlabel++;
   410   		sp->s_sc = sc;
   411   		sp->s_attrib =| SDEFINED;
   412   		if(!infunc)
   413   			sp->s_attrib =| SGLOBAL;
1File: DECL.C                                                              Page       8
   414   	}
   415   	return(size);
   416   }
   417    
   418   /*
   419    * doinit - do external definition initialization
   420    *		Handles following C syntax:
   421    *			initializer:
   422    *					= constant_expression
   423    *					= { initializer_list }
   424    *					= { initializer_list , }
   425    *			initializer_list:
   426    *					constant_expression
   427    *					initializer_list , initializer_list
   428    *					{ initializer_list }
   429    */
   430   doinit(sp)							/* returns number of elements init'ed*/
   431   struct symbol *sp;					/* pointer to symbol to init*/
   432   {
   433   	register int type;
   434   	long isize, datasize, elsize;
   435    
   436   	type = sp->s_type;
   437   	datasize = dsize(type,sp->s_dp,sp->s_ssp);
   438   	if( peek(COMMA) || peek(SEMI) ) {	/*no initialization*/
   439   		isize = walign(datasize);
   440   		if( sp->s_sc == EXTERNAL )
   441   			outcommon(sp->s_symbol,isize);
   442   		else {
   443   			outbss();				/*bss segment*/
   444   			outlab(sp->s_offset);
   445   			outresmem(isize);
   446   			outtext();				/*resume text segment*/
   447   		}
   448   	}
   449   	else {
   450   		next(ASSIGN);				/*ignore '=' if there*/
   451   		if( type == LONG || pointer(type) )
   452   			outldata();
   453   		else if(type == DOUBLE || type == FLOAT)	/*[vlh] 3.4*/
   454   			outfpdata();
   455   		else
   456   			outdata();
   457   		if( sp->s_sc == EXTERNAL )
   458   			outdlab(sp->s_symbol);
   459   		else
   460   			outlab(sp->s_offset);
   461   		isize = initlist(sp->s_type,sp->s_dp,sp->s_ssp);
   462   		if( isize < datasize ) {
   463   			outresmem(datasize-isize);
   464   			isize = datasize;
   465   		}
   466   		if( walign(isize) != isize )
   467   			outpad();
   468   		if( isize > datasize ) {
   469   			if( array(sp->s_type) ) {
   470   				for( type = sp->s_type; array(type); type = delsp(type) )
   471   					;
   472   				dtab[sp->s_dp] = isize / dsize(type,sp->s_dp,sp->s_ssp);
1File: DECL.C                                                              Page       9
   473   			}
   474   			else
   475   				error("too many initializers");
   476   		}
   477   		if( sp->s_sc == STATIC )
   478   			outtext();
   479   	}
   480   }
   481    
   482   /*
   483    * initlist - handles initializer lists
   484    *		This handles multi-level braces, and a character pointer pointing
   485    *		to a string.  Most of the work is in keeping track of how many
   486    *		bytes are left on the current "row", and outputting padding if
   487    *		necessary.
   488    */
   489   long
   490   initlist(type,dp,sp)				/* returns size of initializers in*/
   491   									/* bytes*/
   492   int type;							/* type of data*/
   493   int dp;								/* dimension pointer*/
   494   int sp;								/* structure pointer*/
   495   {
   496   	register int nrows;
   497   	long datasize, i, elsize, nbleft, nbout;	/* [vlh] 3.4 int=>long */
   498   	register int onetype;
   499    
   500   	for( onetype = type; array(onetype); onetype = delsp(onetype) )
   501   		;
   502   	nbout = 0;
   503   	datasize = dsize(type,dp,sp);
   504   	nbleft = 0;						/*keep track of no. of bytes left*/
   505   	if( type == (ARRAY|CHAR) && next(STRING) ) {
   506   		nbout = cstrsize;
   507   		outstr();
   508   		if( datasize > nbout )
   509   			nbleft = datasize - nbout;
   510   	}
   511   	else if( array(type) || (btype(type)==STRUCT && notpointer(type)) ) {
   512   		elsize = datasize / dsize(delsp(type),dp+1,sp);
   513   		elsize = datasize / elsize;
   514   		if(!next(LCURBR))
   515   			error("missing { in initialization");
   516   		if( type == (ARRAY|CHAR) && next(STRING) ) {
   517   			nbout = cstrsize;
   518   			outstr();
   519   			if( datasize > nbout )
   520   				nbleft = datasize - nbout;
   521   		}
   522   		else {
   523   			do {						/*in current row.*/
   524   				if( peek(SEMI) || peek(EOF) )
   525   					break;
   526   				if( peek(LCURBR) ) {	/*recurse down one level?*/
   527   					if( nbleft ) {
   528   						outresmem(nbleft);	/*pad rest of current row*/
   529   						nbout =+ nbleft;
   530   						nbleft = 0;
   531   					}
1File: DECL.C                                                              Page      10
   532   					i = initlist(delsp(type),dp+1,sp);
   533   					if( i > elsize )
   534   						error("initializer list too long");
   535   					else if( i < elsize )
   536   						outresmem(elsize-i);
   537   					nbout =+ elsize;
   538   				}
   539   				else if( peek(RCURBR) )
   540   					break;
   541   				else {
   542   					i = oneinit(onetype);
   543   					nbout =+ i;
   544   					if(!nbleft)
   545   						nbleft = elsize;
   546   					if( i > nbleft )
   547   						error("initializer alignment");
   548   					nbleft = (i >= nbleft) ? 0 : nbleft - i;
   549   				}
   550   			} while( next(COMMA) );
   551   		}
   552   		if(!next(RCURBR))
   553   			synerr("missing }");
   554   	}
   555   	else {
   556   		i = next(LCURBR);			/*pull of optional {*/
   557   		nbout = oneinit(onetype);
   558   		if( i && !next(RCURBR) )
   559   			synerr("missing }");
   560   	}
   561   	if( nbleft ) {					/*pad current row*/
   562   		outresmem(nbleft);
   563   		nbout =+ nbleft;
   564   	}
   565   	return(nbout);
   566   }
   567    
   568   /*
   569    * oneinit - get one initializer expression or constant
   570    *		This checks the type of the data item expected against the
   571    *		type obtained from expr.  Note that there is no attempt to
   572    *		match structure initializations against the elements of the
   573    *		structure, hence, anything goes in a structure.
   574    */
   575   oneinit(type)						/* returns size of initializer*/
   576   int type;							/* type of initializer*/
   577   {
   578   	register int op, value;
   579   	register struct tnode *tp;
   580    
   581   	commastop++;
   582   	tp = expr();
   583   	commastop--;
   584   	op = tp->t_op;
   585   	value = tp->t_value;
   586   	switch( alltype(type) ) {
   587    
   588   	case CHAR:
   589   	case ARRAY|CHAR:
   590   		if( op != CINT )
1File: DECL.C                                                              Page      11
   591   			break;
   592   		outc(CHAR,value);
   593   		return(1);
   594    
   595   	case INT:
   596   	case ARRAY|INT:
   597   	case UNSIGNED:
   598   	case ARRAY|UNSIGNED:
   599   		if( op == CLONG || op == ADDR )
   600   			break;
   601   		if( op == CINT )
   602   			outc(INT,value);
   603   		else
   604   			outinit(tp,inittype);
   605   		return(2);
   606    
   607   	case LONG:
   608   	case ARRAY|LONG:
   609   	case POINTER|CHAR:
   610   	case POINTER|INT:
   611   	case POINTER|LONG:
   612   	case POINTER|STRUCT:
   613   	case POINTER|UNSIGNED:
   614   		if( op == CINT ) {
   615   			clvalue = value;	/*[vlh] fix ??? MC ??? */
   616   			outlong(clvalue);
   617   		}
   618   		else if( op == CLONG )
   619   			outlong(clvalue);
   620   		else
   621   			outinit(tp,inittype);
   622   		return(4);
   623    
   624   	case DOUBLE:	/* [vlh] 3.4 */
   625   	case FLOAT:
   626   		outfp(clvalue);
   627   		return(4);
   628    
   629   	case STRUCT:
   630   	case ARRAY|STRUCT:
   631   		if( op == CINT ) {
   632   			if( xflag ) {
   633   				clvalue = value;
   634   				outlong(clvalue);
   635   				return(4);
   636   			}
   637   			outc(INT,value);
   638   			return(2);
   639   		}
   640   		if( op == CLONG ) {
   641   			outlong(clvalue);
   642   			return(4);
   643   		}
   644   		outinit(tp,inittype);
   645   		if (xflag || op==ADDR) return(4);
   646   		if ((op=tp->t_right->t_op)==ADDR || op==CLONG) return(4); /*[vlh]*/
   647   		if ((op=tp->t_left->t_op)==ADDR || op==CLONG) return(4); /*[vlh]*/
   648   		return(2);
   649   	}
1File: DECL.C                                                              Page      12
   650   	error("invalid initializer");
   651   	return(0);
   652   }
   653    
   654   /*
   655    * funcbody - do function body declaration
   656    *		Basically handles function after we have scanned the parameter
   657    *		list, which is now set up in fargs array.  We now proceed to
   658    *		look for any declarations for the function arguments, then the
   659    *		function declaration list, followed by the function statement list.
   660    *		The C syntax is:
   661    *			function_body:
   662    *					type_decl_list function_statement
   663    *			function_statement:
   664    *					{ declaration_list statement_list }
   665    */
   666   funcbody(fsp)
   667   struct symbol *fsp;
   668   {
   669   	register int olddp;
   670   	register struct symbol *sp;
   671   	register struct farg *fp;
   672   	register int offset, toff;
   673    
   674   	infunc++;
   675   	sp = fsp;
   676   	opap = exprp;
   677   	frp = snalloc(delsp(sp->s_type),sp->s_sc,sp->s_type,sp->s_dp,
   678   			sp->s_ssp);
   679   	exprp = opap;
   680   	outtext();
   681   	outflab(sp->s_symbol);
   682   	olddp = cdp;
   683   	dlist(PDECLIST);
   684   	rlabel = nextlabel++;
   685   	if(!next(LCURBR))
   686   		synerr("function body syntax");
   687   	else {
   688   		localsize = 0;			/*end of first auto offset from l.e.p.*/
   689   		offset = 8;				/*first arg offset from l.e.p.*/
   690   		for( fp = &fargtab[0]; sp = fp->f_sp; fp++ ) {
   691   			toff = offset;
   692   			if( sp->s_type == CHAR )	/*char argument*/
   693   				toff++;			/*offset of lower byte in word*/
   694   			if( sp->s_sc == REGISTER )
   695   				fp->f_offset = toff;
   696   			else {
   697   				fp->f_offset = 0;	/*really is auto arg*/
   698   				sp->s_offset = toff;
   699   				sp->s_sc = AUTO;
   700   			}
   701   			if( array(sp->s_type) ) {	/*change array ref to pointer*/
   702   				sp->s_type = addsp(delsp(sp->s_type),POINTER);
   703   				sp->s_dp++;
   704   			}
   705   			offset =+ walign(dsize(sp->s_type,sp->s_dp,sp->s_ssp));
   706   		}
   707   		dlist(0);
   708   		chksyms();
1File: DECL.C                                                              Page      13
   709   		outbentry(localsize,ndregs,naregs);
   710   		copyargs();				/*copy args to registers where required*/
   711   		while(!next(RCURBR)) {
   712   			if( next(EOF) ) {
   713   				error("{ not matched by }");
   714   				break;
   715   			}
   716   			stmt();
   717   		}
   718   	}
   719   	outlab(rlabel);
   720   	outbexit(ndregs,naregs);
   721   	cdp = olddp;
   722   	infunc--;
   723   	freesyms();
   724   }
   725    
   726   /*
   727    * copyargs - copy args to register where required
   728    *		fargtab has been set so that args declared to be registers have a
   729    *		non-zero offset value and the register number is in the symbol
   730    *		table pointed to by symbol.
   731    */
   732   copyargs()							/* returns - none*/
   733   {
   734   	register struct symbol *sp;
   735   	register struct farg *fp;
   736    
   737   	for( fp = &fargtab[0]; sp = fp->f_sp; fp++ ) {
   738   		if( fp->f_offset )		/*was declared register*/
   739   			outassign(snalloc(sp->s_type,sp->s_sc,sp->s_offset,0,0),
   740   					snalloc(sp->s_type,AUTO,fp->f_offset,0,0));
   741   	}
   742   }
   743    
   744   /*
   745    * dlist - declaration list
   746    *		Handles declaration lists in the following places:
   747    *		function parameter list declarations, structure or union member
   748    *		declarations and local declarations in functions.
   749    */
   750   long
   751   dlist(defsc)						/* returns length of declarators*/
   752   int defsc;							/* default storage class*/
   753   {
   754   	register int offset;
   755   	register struct symbol *sp;
   756   	register long i, ddsize;
   757   	long size;	/* [vlh] 3.4 int => long */
   758   	int type, sc, isize;
   759    
   760   	offset = 0; ddsize = 0L;
   761   	do {
   762   		sc = defsc;
   763   		type = INT;
   764   		if( !gettype(&sc,&type,&size) )
   765   			break;
   766   		do {
   767   			i = dodecl(sc,type,offset,size);
1File: DECL.C                                                              Page      14
   768   			if( defsc != UNELCL ) {
   769   				isize = i;
   770   				offset =+ isize;
   771   				ddsize =+ i;
   772   			}
   773   			else if( i > ddsize )
   774   				ddsize = i;
   775   			if( sc == STATIC && dsp && !stypedef(dsp) )
   776   				doinit(dsp);		/*process any initializer*/
   777   			dsp = 0;
   778   		} while ( next(COMMA) );
   779   		if(!next(SEMI)) {
   780   			synerr("declaration syntax");
   781   			break;
   782   		}
   783   	} while( 1 );
   784   	isize = ddsize;
   785   	ddsize =+ salign(INT,isize);
   786   	return(ddsize);
   787   }
   788    
   789   /*
   790    * declarator - get one declarator
   791    *		Basically uses getdecl, which returns the declaration types
   792    *		reversed in the type word.
   793    */
   794   declarator(castflg)							/* returns type or -1*/
   795   int castflg;
   796   {
   797   	register int type, t;
   798    
   799   	dsp = 0;
   800   	if( (type=getdecl(castflg)) >= 0 )
   801   		return( revsp(type) );
   802   	return(type);
   803   }
   804    
   805   /*
   806    * getdecl - get one declarator, handling *, (), etc.
   807    *		The significance of the value returned by declarator is:  the
   808    *		least significant two bits represent the values (POINTER,FUNCTION,
   809    *		ARRAY), these values are repeated through the word.  For example,
   810    *		the declarations result in the following values for declarator:
   811    *				*x() => (POINTER,FUNCTION)
   812    *				(*x)() => (FUNCTION,POINTER)
   813    *				*(*x)() => (POINTER,FUNCTION,POINTER)
   814    *		The following C syntax is handled here:
   815    *			function_declarator:
   816    *					declarator ( parameter_list )
   817    *			declarator:
   818    *					identifier
   819    *					( declarator )
   820    *					* declarator
   821    *					declarator [ constant-expression ]
   822    */
   823   getdecl(castflg)				/* returns special type of declarator*/
   824   int castflg;					/* casting flag, 1=>allow no declarator*/
   825   {
   826   	register int type, i, value, sdp;
1File: DECL.C                                                              Page      15
   827   	register struct symbol *sp, *tsp;
   828   	register struct farg *fp;
   829   	register char *p;
   830   	long lvalue;
   831    
   832   	type = 0;
   833   	if( next(LPAREN) ) {			/*( declarator ) ...*/
   834   		type = getdecl(castflg);
   835   		if(!next(RPAREN))
   836   			goto baddec;
   837   	}
   838   	if( next(MULT) )
   839   		return(addsp(getdecl(castflg),POINTER));
   840   	sdp = cdp;
   841   	if( next(SYMBOL) ) {
   842   		sp = dsp = csp;
   843   		type = 0;
   844   		sp->s_dp = sdp;
   845   	}
   846   	while( 1 ) {
   847   		if( next(LPAREN) ) {		/*declarator ( ... )*/
   848   			if(!infunc) {
   849   				ndregs = naregs = 0;
   850   				for( fp = &fargtab[0]; next(SYMBOL); ) {
   851   					p = csp;
   852   					if( p->s_attrib & SDEFINED )
   853   						error("redeclaration: %.8s",p->s_symbol);
   854   					else if( fp >= &fargtab[NFARGS-1] ) {
   855   						synerr("too many params");
   856   						break;
   857   					}
   858   					else {
   859   						p->s_attrib =| SDEFINED;
   860   						p->s_sc = PARMLIST;
   861   						p->s_type = INT;	/*default to int*/
   862   						fp->f_sp = p;
   863   						fp++;
   864   					}
   865   					if(!next(COMMA))
   866   						break;
   867   				}
   868   				fp->f_sp = 0;
   869   			}
   870   			if(!next(RPAREN))
   871   				break;
   872   			type = addsp(type,FUNCTION);
   873   			continue;
   874   		}
   875   		if( next(LBRACK) ) {	/*declarator [ cexpr ]*/
   876   			if( next(RBRACK) )
   877   				dalloc(1L);
   878   			else {
   879   				tsp = dsp;			/* [vlh] 3.4 save in case of reset */
   880   				value = cexpr();	/* recurses on sizeof.... resets dsp */
   881   				dsp = tsp;			/* [vlh] 3.4 */
   882   				lvalue = value;		/* [vlh] 3.4 */
   883   				for( i = sdp; i < cdp; )
   884   					dtab[i++] =* lvalue;
   885   				dalloc(lvalue);
1File: DECL.C                                                              Page      16
   886   				if( !next(RBRACK) )
   887   					break;
   888   			}
   889   			type = addsp(type,ARRAY);
   890   			continue;
   891   		}
   892   		if( castflg || dsp )
   893   			return(type);
   894   		break;
   895   	}
   896   baddec:
   897   	synerr("invalid declarator");
   898   	return(-1);
   899   }
   900    
   901   /* dalloc - dimension table allocation*/
   902   /*		Allocates an entry in the dimension table.*/
   903   dalloc(dimsize)						/* returns ptr to dimension allocated*/
   904   long dimsize;						/* dimension size [vlh] 3.4 i=>l*/
   905   {
   906   	register int i;
   907    
   908   	if( (i=cdp++) >= DSIZE-1 )
   909   		ferror("dimension table overflow");
   910   	dtab[i] = dimsize;
   911   	return(i);
   912   }
   913    
   914   /* addsp - add special type to special type info*/
   915   /*		Takes given special type and adds it into the special type field.*/
   916   addsp(type,nsptype)					/* returns resulting type*/
   917   int type;							/* old type field*/
   918   int nsptype;						/* special type to be added*/
   919   {
   920   	register int dtype;
   921    
   922   	dtype = btype(type);
   923   	type =& (~TYPE);
   924   	return( (type<<SUTYPLEN) | suptype(nsptype) | dtype );
   925   }
   926    
   927   /* delsp - delete one special type info field from special type info*/
   928   /*		Takes given special type field and deletes least sign.*/
   929   delsp(type)							/* returns resulting type*/
   930   int type;							/* old special type*/
   931   {
   932   	register int dtype;
   933    
   934   	dtype = btype(type);
   935   	type =& (~(ALLTYPE));
   936   	return( (type>>SUTYPLEN) | dtype );
   937   }
   938    
   939   /*
   940    * revsp - reverse special type info
   941    *		This allows for the processing of the super-type info in
   942    *		the reverse order, which is necessary for initializations.
   943    */
   944   revsp(type)							/* returns reversed type info*/
1File: DECL.C                                                              Page      17
   945   int type;							/* type to reverse*/
   946   {
   947   	register int t;
   948    
   949   	for( t = btype(type); suptype(type) != 0; type = delsp(type) )
   950   		t = addsp(t,type);
   951   	return(t);
   952   }
   953    
   954   /* falign - handle bit field alignments*/
   955   falign(type,flen)					/* returns number of bytes padded*/
   956   int type;							/* data type*/
   957   int flen;							/* field length*/
   958   {
   959   	register int off;
   960    
   961   	off = 0;
   962   	if( flen <= 0 ) {
   963   		error("invalid field size");
   964   		flen = 0;
   965   	}
   966   	switch( type ) {
   967    
   968   	case INT:
   969   	case UNSIGNED:
   970   		if( flen > BITSPWORD )
   971   			error("field overflows word");
   972   		if( flen + boffset > BITSPWORD )
   973   			off = CHRSPWORD;
   974   		break;
   975    
   976   	case CHAR:
   977   		if( flen > BITSPCHAR )
   978   			error("field overflows byte");
   979   		if( flen + boffset > BITSPCHAR )
   980   			off = 1;
   981   		break;
   982    
   983   	default:
   984   		error("invalid field type description");
   985   		return(0);
   986    
   987   	}
   988   	if( off )
   989   		boffset = 0;
   990   	boffset =+ flen;
   991   	return(off);
   992   }
   993    
   994   /* salign - structure alignment*/
   995   salign(type,offset)				/* returns bytes of padding*/
   996   int type;							/* data type to align*/
   997   int offset;							/* current structure offset*/
   998   {
   999   	register int off;
  1000    
  1001   	off = offset;
  1002   	if( boffset ) {					/*remaining bit fields, flush 'em*/
  1003   		off =+ (boffset+(BITSPCHAR-1))/BITSPCHAR;
1File: DECL.C                                                              Page      18
  1004   		boffset = 0;
  1005   	}
  1006   	while( array(type) )			/*get base type*/
  1007   		type = delsp(type);
  1008   	if( type != CHAR )				/*need word boundary*/
  1009   		off = walign(off);
  1010   	return( off - offset );
  1011   }
  1012    
  1013   /* dsize - returns size of data object in bytes*/
  1014   long								/* [vlh] 3.4 */
  1015   dsize(type,dp,sp)					/* returns number of bytes*/
  1016   int type;							/* type of node*/
  1017   int dp;								/* dimension pointer*/
  1018   int sp;								/* size pointer if structure*/
  1019   {
  1020   	register long nel, size;
  1021    
  1022   	nel = 1;
  1023   	for( ; array(type); type = delsp(type) )
  1024   		nel = dtab[dp];
  1025   	if( function(type) )
  1026   		return(0);
  1027   	size = (pointer(type)) ? PTRSIZE : (type == STRUCT) ?
  1028   			dtab[sp] : dinfo[type]&DTSIZE;
  1029   	if(!size)
  1030   		error("invalid data type");
  1031   	return( size * nel );
  1032   }
  1033    
  1034   /*
  1035    * addtdtype - add typedef info into declarator
  1036    *		here we very carefully add in the dimensions for an array typedef
  1037    *		declaration.  Note that declarator has already allocated the
  1038    *		declarator-specific dimensions, now we allocate the typedef
  1039    *		dimensions and adjust the size of the declarator's dimensions.
  1040    *		Note that this must be done before the dalloc for the structure,
  1041    *		otherwise we would mix up array and structure sizes.
  1042    */
  1043   addtdtype(tddp,type,dp,ssp)			/* returns type*/
  1044   struct symbol *tddp;
  1045   int type;
  1046   int dp;
  1047   int *ssp;
  1048   {
  1049   	register int ntype, t, i, tdf;
  1050    
  1051   	for( tdf = 0, t = tddp->s_type; suptype(t); t = delsp(t) )
  1052   		if( array(t) ) {
  1053   			tdf++;
  1054   			break;
  1055   		}
  1056   	ntype = 0;
  1057   	for( t = type, i = dp; suptype(t); t = delsp(t) ) {
  1058   		ntype = addsp(ntype,t);
  1059   		if( tdf && array(t) )
  1060   			dtab[i++] =* dtab[tddp->s_dp];
  1061   	}
  1062   	for( t = tddp->s_type, i = tddp->s_dp; suptype(t); t = delsp(t) )
1File: DECL.C                                                              Page      19
  1063   		if( array(t) )
  1064   			dalloc(dtab[i++]);
  1065   	for( t = tddp->s_type; suptype(ntype); ntype = delsp(ntype) )
  1066   		t = addsp(t,ntype);
  1067   	if( (ntype=btype(t)) == STRUCT )
  1068   		*ssp = tddp->s_ssp;
  1069   	else if( ntype == FRSTRUCT )
  1070   		*ssp = frstp;
  1071   	return(t);
  1072   }
