1 /*	$Id: pftn.c,v 1.393 2014/10/11 10:53:14 ragge Exp $	*/
2 /*
3  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 /*
27  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
28  *
29  * Redistribution and use in source and binary forms, with or without
30  * modification, are permitted provided that the following conditions
31  * are met:
32  *
33  * Redistributions of source code and documentation must retain the above
34  * copyright notice, this list of conditions and the following disclaimer.
35  * Redistributions in binary form must reproduce the above copyright
36  * notice, this list of conditionsand the following disclaimer in the
37  * documentation and/or other materials provided with the distribution.
38  * All advertising materials mentioning features or use of this software
39  * must display the following acknowledgement:
40  * 	This product includes software developed or owned by Caldera
41  *	International, Inc.
42  * Neither the name of Caldera International, Inc. nor the names of other
43  * contributors may be used to endorse or promote products derived from
44  * this software without specific prior written permission.
45  *
46  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
47  * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
48  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
49  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
50  * DISCLAIMED.  IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
51  * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
52  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
53  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
54  * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
55  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
56  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
57  * POSSIBILITY OF SUCH DAMAGE.
58  */
59 
60 /*
61  * Many changes from the 32V sources, among them:
62  * - New symbol table manager (moved to another file).
63  * - Prototype saving/checks.
64  */
65 
66 # include "pass1.h"
67 #include "unicode.h"
68 
69 #include "cgram.h"
70 
71 struct symtab *cftnsp;
72 int arglistcnt, dimfuncnt;	/* statistics */
73 int symtabcnt, suedefcnt;	/* statistics */
74 int autooff,		/* the next unused automatic offset */
75     maxautooff,		/* highest used automatic offset in function */
76     argoff;		/* the next unused argument offset */
77 int retlab = NOLAB;	/* return label for subroutine */
78 int brklab;
79 int contlab;
80 int flostat;
81 int blevel;
82 int reached, prolab;
83 
84 struct params;
85 
86 #define MKTY(p, t, d, s) r = talloc(); *r = *p; \
87 	r = argcast(r, t, d, s); *p = *r; nfree(r);
88 
89 /*
90  * Linked list stack while reading in structs.
91  */
92 struct rstack {
93 	struct	rstack *rnext;
94 	int	rsou;
95 	int	rstr;
96 	struct	symtab *rsym;
97 	struct	symtab *rb;
98 	struct	attr *ap;
99 	int	flags;
100 #define	LASTELM	1
101 } *rpole;
102 
103 /*
104  * Linked list for parameter (and struct elements) declaration.
105  */
106 static struct params {
107 	struct params *prev;
108 	struct symtab *sym;
109 } *lparam;
110 static int nparams;
111 
112 /* defines used for getting things off of the initialization stack */
113 
114 NODE *arrstk[10];
115 int arrstkp;
116 static int intcompare;
117 NODE *parlink;
118 
119 void fixtype(NODE *p, int class);
120 int fixclass(int class, TWORD type);
121 static void dynalloc(struct symtab *p, int *poff);
122 static void evalidx(struct symtab *p);
123 int isdyn(struct symtab *p);
124 void inforce(OFFSZ n);
125 void vfdalign(int n);
126 static void ssave(struct symtab *);
127 #ifdef PCC_DEBUG
128 static void alprint(union arglist *al, int in);
129 #endif
130 static void lcommadd(struct symtab *sp);
131 static NODE *mkcmplx(NODE *p, TWORD dt);
132 static void cxargfixup(NODE *arg, TWORD dt, struct attr *ap);
133 extern int fun_inline;
134 
135 void
defid(NODE * q,int class)136 defid(NODE *q, int class)
137 {
138 	defid2(q, class, 0);
139 }
140 
141 /*
142  * Declaration of an identifier.  Handles redeclarations, hiding,
143  * incomplete types and forward declarations.
144  *
145  * q is a TYPE node setup after parsing with n_type, n_df and n_ap.
146  * n_sp is a pointer to the not-yet initalized symbol table entry
147  * unless it's a redeclaration or supposed to hide a variable.
148  */
149 
150 void
defid2(NODE * q,int class,char * astr)151 defid2(NODE *q, int class, char *astr)
152 {
153 	struct attr *ap;
154 	struct symtab *p;
155 	TWORD type, qual;
156 	TWORD stp, stq;
157 	int scl;
158 	union dimfun *dsym, *ddef;
159 	int slev, temp, changed;
160 
161 	if (q == NIL)
162 		return;  /* an error was detected */
163 
164 #ifdef GCC_COMPAT
165 	gcc_modefix(q);
166 #endif
167 	p = q->n_sp;
168 
169 	if (p->sname == NULL)
170 		cerror("defining null identifier");
171 
172 #ifdef PCC_DEBUG
173 	if (ddebug) {
174 		printf("defid(%s '%s'(%p), ", p->sname, p->soname , p);
175 		tprint(q->n_type, q->n_qual);
176 		printf(", %s, (%p)), level %d\n\t", scnames(class),
177 		    q->n_df, blevel);
178 #ifdef GCC_COMPAT
179 		dump_attr(q->n_ap);
180 #endif
181 	}
182 #endif
183 
184 	fixtype(q, class);
185 
186 	type = q->n_type;
187 	qual = q->n_qual;
188 	class = fixclass(class, type);
189 
190 	stp = p->stype;
191 	stq = p->squal;
192 	slev = p->slevel;
193 
194 #ifdef PCC_DEBUG
195 	if (ddebug) {
196 		printf("	modified to ");
197 		tprint(type, qual);
198 		printf(", %s\n", scnames(class));
199 		printf("	previous def'n: ");
200 		tprint(stp, stq);
201 		printf(", %s, (%p,%p)), level %d\n",
202 		    scnames(p->sclass), p->sdf, p->sap, slev);
203 	}
204 #endif
205 
206 	if (blevel == 1) {
207 		switch (class) {
208 		default:
209 			if (!(class&FIELD) && !ISFTN(type))
210 				uerror("declared argument %s missing",
211 				    p->sname );
212 			break;
213 		case MOS:
214 		case MOU:
215 			cerror("field5");
216 		case TYPEDEF:
217 		case PARAM:
218 			break;
219 		}
220 	}
221 
222 	if (stp == UNDEF)
223 		goto enter; /* New symbol */
224 
225 	if (type != stp)
226 		goto mismatch;
227 
228 	if (blevel > slev && (class == AUTO || class == REGISTER))
229 		/* new scope */
230 		goto mismatch;
231 
232 	/*
233 	 * test (and possibly adjust) dimensions.
234 	 * also check that prototypes are correct.
235 	 */
236 	dsym = p->sdf;
237 	ddef = q->n_df;
238 	changed = 0;
239 	for (temp = type; temp & TMASK; temp = DECREF(temp)) {
240 		if (ISARY(temp)) {
241 			if (dsym->ddim == NOOFFSET) {
242 				dsym->ddim = ddef->ddim;
243 				changed = 1;
244 			} else if (ddef->ddim != NOOFFSET &&
245 			    dsym->ddim!=ddef->ddim) {
246 				goto mismatch;
247 			}
248 			++dsym;
249 			++ddef;
250 		} else if (ISFTN(temp)) {
251 			/* add a late-defined prototype here */
252 			if (!oldstyle && dsym->dfun == NULL)
253 				dsym->dfun = ddef->dfun;
254 			if (!oldstyle && ddef->dfun != NULL &&
255 			    chkftn(dsym->dfun, ddef->dfun))
256 				uerror("declaration doesn't match prototype");
257 			dsym++, ddef++;
258 		}
259 	}
260 #ifdef STABS
261 	if (changed && gflag)
262 		stabs_chgsym(p); /* symbol changed */
263 #endif
264 
265 	/* check that redeclarations are to the same structure */
266 	if (temp == STRTY || temp == UNIONTY) {
267 		if (strmemb(p->sap) != strmemb(q->n_ap))
268 			goto mismatch;
269 	}
270 
271 	scl = p->sclass;
272 
273 #ifdef PCC_DEBUG
274 	if (ddebug)
275 		printf("	previous class: %s\n", scnames(scl));
276 #endif
277 
278 	/*
279 	 * Its allowed to add attributes to existing declarations.
280 	 * Be careful though not to trash existing attributes.
281 	 * XXX - code below is probably not correct.
282 	 */
283 	if (p->sap && p->sap->atype <= ATTR_MAX) {
284 		/* nothing special, just overwrite */
285 		p->sap = q->n_ap;
286 	} else {
287 		if (p->slevel == blevel) {
288 			for (ap = q->n_ap; ap; ap = ap->next) {
289 				if (ap->atype > ATTR_MAX)
290 					p->sap = attr_add(p->sap, attr_dup(ap, 3));
291 			}
292 		} else
293 			p->sap = q->n_ap;
294 	}
295 
296 	if (class & FIELD)
297 		cerror("field1");
298 	switch(class) {
299 
300 	case EXTERN:
301 		if (astr)
302 			p->soname = astr;
303 		switch( scl ){
304 		case STATIC:
305 		case USTATIC:
306 			if( slev==0 )
307 				goto done;
308 			break;
309 		case EXTDEF:
310 		case EXTERN:
311 			goto done;
312 		case SNULL:
313 			if (p->sflags & SINLINE) {
314 				p->sclass = EXTDEF;
315 				inline_ref(p);
316 				goto done;
317 			}
318 			break;
319 		}
320 		break;
321 
322 	case STATIC:
323 		if (astr)
324 			p->soname = astr;
325 		if (scl==USTATIC || (scl==EXTERN && blevel==0)) {
326 			p->sclass = STATIC;
327 			goto done;
328 		}
329 		if (changed || (scl == STATIC && blevel == slev))
330 			goto done; /* identical redeclaration */
331 		break;
332 
333 	case USTATIC:
334 		if (scl==STATIC || scl==USTATIC)
335 			goto done;
336 		break;
337 
338 	case TYPEDEF:
339 		if (scl == class)
340 			goto done;
341 		break;
342 
343 	case MOU:
344 	case MOS:
345 		cerror("field6");
346 
347 	case EXTDEF:
348 		switch (scl) {
349 		case EXTERN:
350 			p->sclass = EXTDEF;
351 			goto done;
352 		case USTATIC:
353 			p->sclass = STATIC;
354 			goto done;
355 		case SNULL:
356 #ifdef GCC_COMPAT
357 			/*
358 			 * Handle redeclarations of inlined functions.
359 			 * This is allowed if the previous declaration is of
360 			 * type gnu_inline.
361 			 */
362 			if (attr_find(p->sap, GCC_ATYP_GNU_INLINE))
363 				goto done;
364 #endif
365 			break;
366 		}
367 		break;
368 
369 	case AUTO:
370 	case REGISTER:
371 		break;  /* mismatch.. */
372 	case SNULL:
373 		if (fun_inline && ISFTN(type)) {
374 			if (scl == EXTERN) {
375 				p->sclass = EXTDEF;
376 				inline_ref(p);
377 			}
378 			goto done;
379 		}
380 		break;
381 	}
382 
383 	mismatch:
384 
385 	/*
386 	 * Only allowed for automatic variables.
387 	 */
388 	if ((blevel == 2 && slev == 1) || blevel <= slev || class == EXTERN) {
389 		uerror("redeclaration of %s", p->sname);
390 		return;
391 	}
392 	q->n_sp = p = hide(p);
393 
394 	enter:  /* make a new entry */
395 
396 #ifdef PCC_DEBUG
397 	if(ddebug)
398 		printf("	new entry made\n");
399 #endif
400 	p->stype = type;
401 	p->squal = qual;
402 	p->sclass = (char)class;
403 	p->slevel = (char)blevel;
404 	p->soffset = NOOFFSET;
405 	if (q->n_ap)
406 		p->sap = attr_add(q->n_ap, p->sap);
407 
408 	/* copy dimensions */
409 	p->sdf = q->n_df;
410 	/* Do not save param info for old-style functions */
411 	if (ISFTN(type) && oldstyle)
412 		p->sdf->dfun = NULL;
413 
414 	if (arrstkp)
415 		evalidx(p);
416 
417 	/* allocate offsets */
418 	if (class&FIELD) {
419 		cerror("field2");  /* new entry */
420 	} else switch (class) {
421 
422 	case REGISTER:
423 		if (astr != NULL)
424 			werror("no register assignment (yet)");
425 		p->sclass = class = AUTO;
426 		/* FALLTHROUGH */
427 	case AUTO:
428 		if (isdyn(p)) {
429 			p->sflags |= SDYNARRAY;
430 			dynalloc(p, &autooff);
431 		} else
432 			oalloc(p, &autooff);
433 		break;
434 
435 	case PARAM:
436 		if (q->n_type != FARG)
437 			oalloc(p, &argoff);
438 		break;
439 
440 	case STATIC:
441 	case EXTDEF:
442 	case EXTERN:
443 		p->soffset = getlab();
444 		/* FALLTHROUGH */
445 	case USTATIC:
446 		if (astr)
447 			p->soname = astr;
448 		break;
449 
450 	case MOU:
451 	case MOS:
452 		cerror("field7");
453 	case SNULL:
454 #ifdef notdef
455 		if (fun_inline) {
456 			p->slevel = 1;
457 			p->soffset = getlab();
458 		}
459 #endif
460 		break;
461 	}
462 
463 #ifdef STABS
464 	if (gflag && p->stype != FARG)
465 		stabs_newsym(p);
466 #endif
467 
468 done:
469 	fixdef(p);	/* Leave last word to target */
470 #ifndef HAVE_WEAKREF
471 	{
472 		struct attr *at;
473 
474 		/* Refer renamed function */
475 		if ((at = attr_find(p->sap, GCC_ATYP_WEAKREF)))
476 			p->soname = at->sarg(0);
477 	}
478 #endif
479 #ifdef PCC_DEBUG
480 	if (ddebug) {
481 		printf( "	sdf, offset: %p, %d\n\t",
482 		    p->sdf, p->soffset);
483 #ifdef GCC_COMPAT
484 		dump_attr(p->sap);
485 #endif
486 	}
487 #endif
488 }
489 
490 void
ssave(struct symtab * sym)491 ssave(struct symtab *sym)
492 {
493 	struct params *p;
494 
495 	p = tmpalloc(sizeof(struct params));
496 	p->prev = lparam;
497 	p->sym = sym;
498 	lparam = p;
499 }
500 
501 /*
502  * end of function
503  */
504 void
ftnend(void)505 ftnend(void)
506 {
507 #ifdef GCC_COMPAT
508 	struct attr *gc, *gd;
509 #endif
510 	extern int *mkclabs(void);
511 	extern NODE *cftnod;
512 	extern struct savbc *savbc;
513 	extern struct swdef *swpole;
514 	extern int tvaloff;
515 	char *c;
516 
517 	if (retlab != NOLAB && nerrors == 0) { /* inside a real function */
518 		plabel(retlab);
519 		if (cftnod)
520 			ecomp(buildtree(FORCE, cftnod, NIL));
521 		efcode(); /* struct return handled here */
522 		if ((c = cftnsp->soname) == NULL)
523 			c = addname(exname(cftnsp->sname));
524 		SETOFF(maxautooff, ALCHAR);
525 		send_passt(IP_EPILOG, maxautooff/SZCHAR, c,
526 		    cftnsp->stype, cftnsp->sclass == EXTDEF,
527 		    retlab, tvaloff, mkclabs());
528 	}
529 
530 	cftnod = NIL;
531 	tcheck();
532 	brklab = contlab = retlab = NOLAB;
533 	flostat = 0;
534 	if (nerrors == 0) {
535 		if (savbc != NULL)
536 			cerror("bcsave error");
537 		if (lparam != NULL)
538 			cerror("parameter reset error");
539 		if (swpole != NULL)
540 			cerror("switch error");
541 	}
542 #ifdef GCC_COMPAT
543 	if (cftnsp) {
544 		gc = attr_find(cftnsp->sap, GCC_ATYP_CONSTRUCTOR);
545 		gd = attr_find(cftnsp->sap, GCC_ATYP_DESTRUCTOR);
546 		if (gc || gd) {
547 			struct symtab sts = *cftnsp;
548 			NODE *p;
549 			sts.stype = INCREF(sts.stype);
550 			p = nametree(&sts);
551 			p->n_op = ICON;
552 			if (gc) {
553 				locctr(CTORS, NULL);
554 				inval(0, SZPOINT(0), p);
555 			}
556 			if (gd) {
557 				locctr(DTORS, NULL);
558 				inval(0, SZPOINT(0), p);
559 			}
560 			tfree(p);
561 		}
562 	}
563 #endif
564 	savbc = NULL;
565 	lparam = NULL;
566 	cftnsp = NULL;
567 	maxautooff = autooff = AUTOINIT;
568 	reached = 1;
569 
570 	if (isinlining)
571 		inline_end();
572 	inline_prtout();
573 
574 	tmpfree(); /* Release memory resources */
575 }
576 
577 static struct symtab nulsym = {
578 	NULL, 0, 0, 0, 0, "null", "null", INT, 0, NULL, NULL
579 };
580 
581 void
dclargs(void)582 dclargs(void)
583 {
584 	union dimfun *df;
585 	union arglist *al, *al2, *alb;
586 	struct params *a;
587 	struct symtab *p, **parr = NULL; /* XXX gcc */
588 	int i;
589 
590 	/*
591 	 * Deal with fun(void) properly.
592 	 */
593 	if (nparams == 1 && lparam->sym && lparam->sym->stype == VOID)
594 		goto done;
595 
596 	/*
597 	 * Generate a list for bfcode().
598 	 * Parameters were pushed in reverse order.
599 	 */
600 	if (nparams != 0)
601 		parr = tmpalloc(sizeof(struct symtab *) * nparams);
602 
603 	if (nparams)
604 	    for (a = lparam, i = 0; a != NULL; a = a->prev) {
605 		p = a->sym;
606 		parr[i++] = p;
607 		if (p == NULL) {
608 			uerror("parameter %d name missing", i);
609 			p = &nulsym; /* empty symtab */
610 		}
611 		if (p->stype == FARG)
612 			p->stype = INT;
613 		if (ISARY(p->stype)) {
614 			p->stype += (PTR-ARY);
615 			p->sdf++;
616 		} else if (ISFTN(p->stype)) {
617 			werror("function declared as argument");
618 			p->stype = INCREF(p->stype);
619 		}
620 #ifdef STABS
621 		if (gflag)
622 			stabs_newsym(p);
623 #endif
624 	}
625 	if (oldstyle && (df = cftnsp->sdf) && (al = df->dfun)) {
626 		/*
627 		 * Check against prototype of oldstyle function.
628 		 */
629 		alb = al2 = tmpalloc(sizeof(union arglist) * nparams * 3 + 1);
630 		for (i = 0; i < nparams; i++) {
631 			TWORD type = parr[i]->stype;
632 			(al2++)->type = type;
633 			if (ISSOU(BTYPE(type)))
634 				(al2++)->sap = parr[i]->sap;
635 			while (!ISFTN(type) && !ISARY(type) && type > BTMASK)
636 				type = DECREF(type);
637 			if (type > BTMASK)
638 				(al2++)->df = parr[i]->sdf;
639 		}
640 		al2->type = TNULL;
641 		intcompare = 1;
642 		if (chkftn(al, alb))
643 			uerror("function doesn't match prototype");
644 		intcompare = 0;
645 
646 	}
647 
648 	if (oldstyle && nparams) {
649 		/* Must recalculate offset for oldstyle args here */
650 		argoff = ARGINIT;
651 		for (i = 0; i < nparams; i++) {
652 			parr[i]->soffset = NOOFFSET;
653 			oalloc(parr[i], &argoff);
654 		}
655 	}
656 
657 done:	autooff = AUTOINIT;
658 
659 	plabel(prolab); /* after prolog, used in optimization */
660 	retlab = getlab();
661 	bfcode(parr, nparams);
662 	if (fun_inline && (xinline
663 #ifdef GCC_COMPAT
664  || attr_find(cftnsp->sap, GCC_ATYP_ALW_INL)
665 #endif
666 		))
667 		inline_args(parr, nparams);
668 	plabel(getlab()); /* used when spilling */
669 	if (parlink)
670 		ecomp(parlink);
671 	parlink = NIL;
672 	lparam = NULL;
673 	nparams = 0;
674 	symclear(1);	/* In case of function pointer args */
675 }
676 
677 /*
678  * basic attributes for structs and enums
679  */
680 static struct attr *
seattr(void)681 seattr(void)
682 {
683 	return attr_add(attr_new(ATTR_ALIGNED, 4), attr_new(ATTR_STRUCT, 2));
684 }
685 
686 /*
687  * Struct/union/enum symtab construction.
688  */
689 static void
defstr(struct symtab * sp,int class)690 defstr(struct symtab *sp, int class)
691 {
692 	sp->sclass = (char)class;
693 	if (class == STNAME)
694 		sp->stype = STRTY;
695 	else if (class == UNAME)
696 		sp->stype = UNIONTY;
697 	else if (class == ENAME)
698 		sp->stype = ENUMTY;
699 }
700 
701 /*
702  * Declare a struct/union/enum tag.
703  * If not found, create a new tag with UNDEF type.
704  */
705 static struct symtab *
deftag(char * name,int class)706 deftag(char *name, int class)
707 {
708 	struct symtab *sp;
709 
710 	if ((sp = lookup(name, STAGNAME))->sap == NULL) {
711 		/* New tag */
712 		defstr(sp, class);
713 	} else if (sp->sclass != class)
714 		uerror("tag %s redeclared", name);
715 	return sp;
716 }
717 
718 /*
719  * reference to a structure or union, with no definition
720  */
721 NODE *
rstruct(char * tag,int soru)722 rstruct(char *tag, int soru)
723 {
724 	struct symtab *sp;
725 
726 	sp = deftag(tag, soru);
727 	if (sp->sap == NULL)
728 		sp->sap = seattr();
729 	return mkty(sp->stype, 0, sp->sap);
730 }
731 
732 static int enumlow, enumhigh;
733 int enummer;
734 
735 /*
736  * Declare a member of enum.
737  */
738 void
moedef(char * name)739 moedef(char *name)
740 {
741 	struct symtab *sp;
742 
743 	sp = lookup(name, SNORMAL);
744 	if (sp->stype == UNDEF || (sp->slevel < blevel)) {
745 		if (sp->stype != UNDEF)
746 			sp = hide(sp);
747 		sp->stype = INT; /* always */
748 		sp->sclass = MOE;
749 		sp->soffset = enummer;
750 	} else
751 		uerror("%s redeclared", name);
752 	if (enummer < enumlow)
753 		enumlow = enummer;
754 	if (enummer > enumhigh)
755 		enumhigh = enummer;
756 	enummer++;
757 }
758 
759 /*
760  * Declare an enum tag.  Complain if already defined.
761  */
762 struct symtab *
enumhd(char * name)763 enumhd(char *name)
764 {
765 	struct attr *ap;
766 	struct symtab *sp;
767 
768 	enummer = enumlow = enumhigh = 0;
769 	if (name == NULL)
770 		return NULL;
771 
772 	sp = deftag(name, ENAME);
773 	if (sp->stype != ENUMTY) {
774 		if (sp->slevel == blevel)
775 			uerror("%s redeclared", name);
776 		sp = hide(sp);
777 		defstr(sp, ENAME);
778 	}
779 	if (sp->sap == NULL)
780 		ap = sp->sap = attr_new(ATTR_STRUCT, 4);
781 	else
782 		ap = attr_find(sp->sap, ATTR_STRUCT);
783 	ap->amlist = sp;
784 	return sp;
785 }
786 
787 /*
788  * finish declaration of an enum
789  */
790 NODE *
enumdcl(struct symtab * sp)791 enumdcl(struct symtab *sp)
792 {
793 	NODE *p;
794 	TWORD t;
795 
796 #ifdef ENUMSIZE
797 	t = ENUMSIZE(enumhigh, enumlow);
798 #else
799 	t = ctype(enumlow < 0 ? INT : UNSIGNED);
800 #ifdef notdef
801 	if (enumhigh <= MAX_CHAR && enumlow >= MIN_CHAR)
802 		t = ctype(CHAR);
803 	else if (enumhigh <= MAX_SHORT && enumlow >= MIN_SHORT)
804 		t = ctype(SHORT);
805 	else
806 		t = ctype(INT);
807 #endif
808 #endif
809 
810 	if (sp)
811 		sp->stype = t;
812 	p = mkty(t, 0, 0);
813 	p->n_sp = sp;
814 	return p;
815 }
816 
817 /*
818  * Handle reference to an enum
819  */
820 NODE *
enumref(char * name)821 enumref(char *name)
822 {
823 	struct symtab *sp;
824 	NODE *p;
825 
826 	sp = lookup(name, STAGNAME);
827 
828 #ifdef notdef
829 	/*
830 	 * 6.7.2.3 Clause 2:
831 	 * "A type specifier of the form 'enum identifier' without an
832 	 *  enumerator list shall only appear after the type it specifies
833 	 *  is complete."
834 	 */
835 	if (sp->sclass != ENAME)
836 		uerror("enum %s undeclared", name);
837 #endif
838 	if (sp->sclass == SNULL) {
839 		/* declare existence of enum */
840 		sp = enumhd(name);
841 		sp->stype = ENUMTY;
842 	}
843 
844 	p = mkty(sp->stype, 0, sp->sap);
845 	p->n_sp = sp;
846 	return p;
847 }
848 
849 /*
850  * begining of structure or union declaration
851  * It's an error if this routine is called twice with the same struct.
852  */
853 struct rstack *
bstruct(char * name,int soru,NODE * gp)854 bstruct(char *name, int soru, NODE *gp)
855 {
856 	struct rstack *r;
857 	struct symtab *sp;
858 	struct attr *ap, *gap;
859 
860 #ifdef GCC_COMPAT
861 	gap = gp ? gcc_attr_parse(gp) : NULL;
862 #else
863 	gap = NULL;
864 #endif
865 
866 	if (name != NULL) {
867 		sp = deftag(name, soru);
868 		if (sp->sap == NULL)
869 			sp->sap = seattr();
870 		ap = attr_find(sp->sap, ATTR_ALIGNED);
871 		if (ap->iarg(0) != 0) {
872 			if (sp->slevel < blevel) {
873 				sp = hide(sp);
874 				defstr(sp, soru);
875 				sp->sap = seattr();
876 			} else
877 				uerror("%s redeclared", name);
878 		}
879 		gap = sp->sap = attr_add(sp->sap, gap);
880 	} else {
881 		gap = attr_add(seattr(), gap);
882 		sp = NULL;
883 	}
884 
885 	r = tmpcalloc(sizeof(struct rstack));
886 	r->rsou = soru;
887 	r->rsym = sp;
888 	r->rb = NULL;
889 	r->ap = gap;
890 	r->rnext = rpole;
891 	rpole = r;
892 
893 	return r;
894 }
895 
896 /*
897  * Called after a struct is declared to restore the environment.
898  * - If ALSTRUCT is defined, this will be the struct alignment and the
899  *   struct size will be a multiple of ALSTRUCT, otherwise it will use
900  *   the alignment of the largest struct member.
901  */
902 NODE *
dclstruct(struct rstack * r)903 dclstruct(struct rstack *r)
904 {
905 	NODE *n;
906 	struct attr *aps, *apb;
907 	struct symtab *sp;
908 	int al, sa, sz;
909 
910 	apb = attr_find(r->ap, ATTR_ALIGNED);
911 	aps = attr_find(r->ap, ATTR_STRUCT);
912 	aps->amlist = r->rb;
913 
914 #ifdef ALSTRUCT
915 	al = ALSTRUCT;
916 #else
917 	al = ALCHAR;
918 #endif
919 
920 	/*
921 	 * extract size and alignment, calculate offsets
922 	 */
923 	for (sp = r->rb; sp; sp = sp->snext) {
924 		sa = talign(sp->stype, sp->sap);
925 		if (sp->sclass & FIELD)
926 			sz = sp->sclass&FLDSIZ;
927 		else
928 			sz = (int)tsize(sp->stype, sp->sdf, sp->sap);
929 		if (sz > rpole->rstr)
930 			rpole->rstr = sz;  /* for use with unions */
931 		/*
932 		 * set al, the alignment, to the lcm of the alignments
933 		 * of the members.
934 		 */
935 		SETOFF(al, sa);
936 	}
937 
938 	SETOFF(rpole->rstr, al);
939 
940 	aps->amsize = rpole->rstr;
941 	apb->iarg(0) = al;
942 
943 #ifdef PCC_DEBUG
944 	if (ddebug) {
945 		printf("dclstruct(%s): size=%d, align=%d\n",
946 		    r->rsym ? r->rsym->sname : "??",
947 		    aps->amsize, apb->iarg(0));
948 	}
949 	if (ddebug>1) {
950 		printf("\tsize %d align %d link %p\n",
951 		    aps->amsize, apb->iarg(0), aps->amlist);
952 		for (sp = aps->amlist; sp != NULL; sp = sp->snext) {
953 			printf("\tmember %s(%p)\n", sp->sname, sp);
954 		}
955 	}
956 #endif
957 
958 #ifdef STABS
959 	if (gflag)
960 		stabs_struct(r->rsym, r->ap);
961 #endif
962 
963 	rpole = r->rnext;
964 	n = mkty(r->rsou == STNAME ? STRTY : UNIONTY, 0, r->ap);
965 	n->n_sp = r->rsym;
966 
967 	n->n_qual |= 1; /* definition place XXX used by attributes */
968 	return n;
969 }
970 
971 /*
972  * Add a new member to the current struct or union being declared.
973  */
974 void
soumemb(NODE * n,char * name,int class)975 soumemb(NODE *n, char *name, int class)
976 {
977 	struct symtab *sp, *lsp;
978 	int incomp, tsz, al;
979 	TWORD t;
980 
981 	if (rpole == NULL)
982 		cerror("soumemb");
983 
984 	/* check if tag name exists */
985 	lsp = NULL;
986 	for (sp = rpole->rb; sp != NULL; lsp = sp, sp = sp->snext)
987 		if (*name != '*' && sp->sname == name)
988 			uerror("redeclaration of %s", name);
989 
990 	sp = getsymtab(name, SMOSNAME);
991 	if (rpole->rb == NULL)
992 		rpole->rb = sp;
993 	else
994 		lsp->snext = sp;
995 
996 	n->n_sp = sp;
997 	sp->stype = n->n_type;
998 	sp->squal = n->n_qual;
999 	sp->slevel = blevel;
1000 	sp->sap = n->n_ap;
1001 	sp->sdf = n->n_df;
1002 
1003 	if (class & FIELD) {
1004 		sp->sclass = (char)class;
1005 		if (rpole->rsou == UNAME)
1006 			rpole->rstr = 0;
1007 		falloc(sp, class&FLDSIZ, NIL);
1008 	} else if (rpole->rsou == STNAME || rpole->rsou == UNAME) {
1009 		sp->sclass = rpole->rsou == STNAME ? MOS : MOU;
1010 		if (sp->sclass == MOU)
1011 			rpole->rstr = 0;
1012 		al = talign(sp->stype, sp->sap);
1013 		tsz = (int)tsize(sp->stype, sp->sdf, sp->sap);
1014 		sp->soffset = upoff(tsz, al, &rpole->rstr);
1015 	}
1016 
1017 	/*
1018 	 * 6.7.2.1 clause 16:
1019 	 * "...the last member of a structure with more than one
1020 	 *  named member may have incomplete array type;"
1021 	 */
1022 	if (ISARY(sp->stype) && sp->sdf->ddim == NOOFFSET)
1023 		incomp = 1;
1024 	else
1025 		incomp = 0;
1026 	if ((rpole->flags & LASTELM) || (rpole->rb == sp && incomp == 1))
1027 		uerror("incomplete array in struct");
1028 	if (incomp == 1)
1029 		rpole->flags |= LASTELM;
1030 
1031 	/*
1032 	 * 6.7.2.1 clause 2:
1033 	 * "...such a structure shall not be a member of a structure
1034 	 *  or an element of an array."
1035 	 */
1036 	t = sp->stype;
1037 	if (rpole->rsou != STNAME || BTYPE(t) != STRTY)
1038 		return; /* not for unions */
1039 	while (ISARY(t))
1040 		t = DECREF(t);
1041 	if (ISPTR(t))
1042 		return;
1043 
1044 	if ((lsp = strmemb(sp->sap)) != NULL) {
1045 		for (; lsp->snext; lsp = lsp->snext)
1046 			;
1047 		if (ISARY(lsp->stype) && lsp->snext &&
1048 		    lsp->sdf->ddim == NOOFFSET)
1049 			uerror("incomplete struct in struct");
1050 	}
1051 }
1052 
1053 /*
1054  * error printing routine in parser
1055  */
1056 void
yyerror(char * s)1057 yyerror(char *s)
1058 {
1059 	uerror(s);
1060 }
1061 
1062 void yyaccpt(void);
1063 void
yyaccpt(void)1064 yyaccpt(void)
1065 {
1066 	ftnend();
1067 }
1068 
1069 /*
1070  * p is top of type list given to tymerge later.
1071  * Find correct CALL node and declare parameters from there.
1072  */
1073 void
ftnarg(NODE * p)1074 ftnarg(NODE *p)
1075 {
1076 	NODE *q;
1077 
1078 #ifdef PCC_DEBUG
1079 	if (ddebug > 2)
1080 		printf("ftnarg(%p)\n", p);
1081 #endif
1082 	/*
1083 	 * Push argument symtab entries onto param stack in reverse order,
1084 	 * due to the nature of the stack it will be reclaimed correct.
1085 	 */
1086 	for (; p->n_op != NAME; p = p->n_left) {
1087 		if (p->n_op == UCALL && p->n_left->n_op == NAME)
1088 			return;	/* Nothing to enter */
1089 		if (p->n_op == CALL && p->n_left->n_op == NAME)
1090 			break;
1091 	}
1092 
1093 	p = p->n_right;
1094 	while (p->n_op == CM) {
1095 		q = p->n_right;
1096 		if (q->n_op != ELLIPSIS) {
1097 			ssave(q->n_sp);
1098 			nparams++;
1099 #ifdef PCC_DEBUG
1100 			if (ddebug > 2)
1101 				printf("	saving sym %s (%p) from (%p)\n",
1102 				    q->n_sp->sname, q->n_sp, q);
1103 #endif
1104 		}
1105 		p = p->n_left;
1106 	}
1107 	ssave(p->n_sp);
1108 	if (p->n_type != VOID)
1109 		nparams++;
1110 
1111 #ifdef PCC_DEBUG
1112 	if (ddebug > 2)
1113 		printf("	saving sym %s (%p) from (%p)\n",
1114 		    nparams ? p->n_sp->sname : "<noname>", p->n_sp, p);
1115 #endif
1116 }
1117 
1118 /*
1119  * compute the alignment of an object with type ty, sizeoff index s
1120  */
1121 int
talign(unsigned int ty,struct attr * apl)1122 talign(unsigned int ty, struct attr *apl)
1123 {
1124 	struct attr *al;
1125 	int a;
1126 
1127 	for (; ty > BTMASK; ty = DECREF(ty)) {
1128 		switch (ty & TMASK) {
1129 		case PTR:
1130 			return(ALPOINT);
1131 		case ARY:
1132 			continue;
1133 		case FTN:
1134 			cerror("compiler takes alignment of function");
1135 		}
1136 	}
1137 
1138 	/* check for alignment attribute */
1139 	if ((al = attr_find(apl, ATTR_ALIGNED))) {
1140 		if ((a = al->iarg(0)) == 0) {
1141 			uerror("no alignment");
1142 			a = ALINT;
1143 		}
1144 		return a;
1145 	}
1146 
1147 #ifndef NO_COMPLEX
1148 	if (ISITY(ty))
1149 		ty -= (FIMAG-FLOAT);
1150 #endif
1151 	ty = BTYPE(ty);
1152 	if (ty >= CHAR && ty <= ULONGLONG && ISUNSIGNED(ty))
1153 		ty = DEUNSIGN(ty);
1154 
1155 	switch (ty) {
1156 #ifdef GCC_COMPAT
1157 	case VOID: a = ALCHAR; break; /* GCC */
1158 #endif
1159 	case BOOL: a = ALBOOL; break;
1160 	case CHAR: a = ALCHAR; break;
1161 	case SHORT: a = ALSHORT; break;
1162 	case INT: a = ALINT; break;
1163 	case LONG: a = ALLONG; break;
1164 	case LONGLONG: a = ALLONGLONG; break;
1165 	case FLOAT: a = ALFLOAT; break;
1166 	case DOUBLE: a = ALDOUBLE; break;
1167 	case LDOUBLE: a = ALLDOUBLE; break;
1168 	default:
1169 		uerror("no alignment");
1170 		a = ALINT;
1171 	}
1172 	return a;
1173 }
1174 
1175 short sztable[] = { 0, SZBOOL, SZCHAR, SZCHAR, SZSHORT, SZSHORT, SZINT, SZINT,
1176 	SZLONG, SZLONG, SZLONGLONG, SZLONGLONG, SZFLOAT, SZDOUBLE, SZLDOUBLE };
1177 
1178 /* compute the size associated with type ty,
1179  *  dimoff d, and sizoff s */
1180 /* BETTER NOT BE CALLED WHEN t, d, and s REFER TO A BIT FIELD... */
1181 OFFSZ
tsize(TWORD ty,union dimfun * d,struct attr * apl)1182 tsize(TWORD ty, union dimfun *d, struct attr *apl)
1183 {
1184 	struct attr *ap, *ap2;
1185 	OFFSZ mult, sz;
1186 
1187 	mult = 1;
1188 
1189 	for (; ty > BTMASK; ty = DECREF(ty)) {
1190 		switch (ty & TMASK) {
1191 
1192 		case FTN:
1193 			uerror( "cannot take size of function");
1194 		case PTR:
1195 			return( SZPOINT(ty) * mult );
1196 		case ARY:
1197 			if (d->ddim == NOOFFSET)
1198 				return 0;
1199 			if (d->ddim < 0)
1200 				cerror("tsize: dynarray");
1201 			mult *= d->ddim;
1202 			d++;
1203 		}
1204 	}
1205 
1206 #ifndef NO_COMPLEX
1207 	if (ISITY(ty))
1208 		ty -= (FIMAG-FLOAT);
1209 #endif
1210 
1211 	if (ty == VOID)
1212 		ty = CHAR;
1213 	if (ty <= LDOUBLE)
1214 		sz = sztable[ty];
1215 	else if (ISSOU(ty)) {
1216 		if ((ap = strattr(apl)) == NULL ||
1217 		    (ap2 = attr_find(apl, ATTR_ALIGNED)) == NULL ||
1218 		    (ap2->iarg(0) == 0)) {
1219 			uerror("unknown structure/union/enum");
1220 			sz = SZINT;
1221 		} else
1222 			sz = ap->amsize;
1223 	} else {
1224 		uerror("unknown type");
1225 		sz = SZINT;
1226 	}
1227 
1228 	return((unsigned int)sz * mult);
1229 }
1230 
1231 /*
1232  * Save string (and print it out).  If wide then wide string.
1233  */
1234 NODE *
strend(int wide,char * str)1235 strend(int wide, char *str)
1236 {
1237 	struct symtab *sp;
1238 	NODE *p;
1239 
1240 	/* If an identical string is already emitted, just forget this one */
1241 	if (wide) {
1242 		/* Do not save wide strings, at least not now */
1243 		sp = getsymtab(str, SSTRING|STEMP);
1244 	} else {
1245 		str = addstring(str);	/* enter string in string table */
1246 		sp = lookup(str, SSTRING);	/* check for existence */
1247 	}
1248 
1249 	if (sp->soffset == 0) { /* No string */
1250 		char *wr;
1251 		int i;
1252 
1253 		sp->sclass = STATIC;
1254 		sp->slevel = 1;
1255 		sp->soffset = getlab();
1256 		sp->squal = (CON >> TSHIFT);
1257 		sp->sdf = permalloc(sizeof(union dimfun));
1258 		if (wide) {
1259 			sp->stype = WCHAR_TYPE+ARY;
1260 		} else {
1261 			if (xuchar) {
1262 				sp->stype = UCHAR+ARY;
1263 			} else {
1264 				sp->stype = CHAR+ARY;
1265 			}
1266 		}
1267 		for (wr = sp->sname, i = 1; *wr; i++) {
1268 			if (wide)
1269 				(void)u82cp(&wr);
1270 			else if (*wr == '\\')
1271 				(void)esccon(&wr);
1272 			else
1273 				wr++;
1274 		}
1275 		sp->sdf->ddim = i;
1276 
1277 		if (wide)
1278 			inwstring(sp);
1279 		else
1280 			instring(sp);
1281 	}
1282 
1283 	p = block(NAME, NIL, NIL, sp->stype, sp->sdf, sp->sap);
1284 	p->n_sp = sp;
1285 	return(clocal(p));
1286 }
1287 
1288 /*
1289  * Print out a wide string by calling ninval().
1290  */
1291 void
inwstring(struct symtab * sp)1292 inwstring(struct symtab *sp)
1293 {
1294 	char *s = sp->sname;
1295 	NODE *p;
1296 	int n;
1297 
1298 	locctr(STRNG, sp);
1299 	defloc(sp);
1300 	p = xbcon(0, NULL, WCHAR_TYPE);
1301 	for (n = sp->sdf->ddim; n > 0; n--) {
1302 		p->n_lval = u82cp(&s);
1303 		inval(0, tsize(WCHAR_TYPE, NULL, NULL), p);
1304 	}
1305 	nfree(p);
1306 }
1307 
1308 #ifndef MYINSTRING
1309 /*
1310  * Print out a string of characters.
1311  * Assume that the assembler understands C-style escape
1312  * sequences.
1313  */
1314 void
instring(struct symtab * sp)1315 instring(struct symtab *sp)
1316 {
1317 	char *s, *str;
1318 
1319 	locctr(STRNG, sp);
1320 	defloc(sp);
1321 
1322 	printf("\t.ascii \"");
1323 	str = s = sp->sname;
1324 	while (*s) {
1325 		if (*s == '\\')
1326 			(void)esccon(&s);
1327 		else
1328 			s++;
1329 
1330 		if (s - str > 60) {
1331 			fwrite(str, 1, s - str, stdout);
1332 			printf("\"\n\t.ascii \"");
1333 			str = s;
1334 		}
1335 	}
1336 
1337 	fwrite(str, 1, s - str, stdout);
1338 	printf("\\0\"\n");
1339 }
1340 #endif
1341 
1342 /*
1343  * update the offset pointed to by poff; return the
1344  * offset of a value of size `size', alignment `alignment',
1345  * given that off is increasing
1346  */
1347 int
upoff(int size,int alignment,int * poff)1348 upoff(int size, int alignment, int *poff)
1349 {
1350 	int off;
1351 
1352 	off = *poff;
1353 	SETOFF(off, alignment);
1354 	if (off < 0)
1355 		cerror("structure or stack overgrown"); /* wrapped */
1356 	*poff = off+size;
1357 	return (off);
1358 }
1359 
1360 /*
1361  * allocate p with offset *poff, and update *poff
1362  */
1363 int
oalloc(struct symtab * p,int * poff)1364 oalloc(struct symtab *p, int *poff )
1365 {
1366 	int al, off, tsz;
1367 	int noff;
1368 
1369 	/*
1370 	 * Only generate tempnodes if we are optimizing,
1371 	 * and only for integers, floats or pointers,
1372 	 * and not if the type on this level is volatile.
1373 	 */
1374 	if (xtemps && ((p->sclass == AUTO) || (p->sclass == REGISTER)) &&
1375 	    (p->stype < STRTY || ISPTR(p->stype)) &&
1376 	    !(cqual(p->stype, p->squal) & VOL) && cisreg(p->stype)) {
1377 		NODE *tn = tempnode(0, p->stype, p->sdf, p->sap);
1378 		p->soffset = regno(tn);
1379 		p->sflags |= STNODE;
1380 		nfree(tn);
1381 		return 0;
1382 	}
1383 
1384 	al = talign(p->stype, p->sap);
1385 	noff = off = *poff;
1386 	tsz = (int)tsize(p->stype, p->sdf, p->sap);
1387 #ifdef BACKAUTO
1388 	if (p->sclass == AUTO) {
1389 		noff = off + tsz;
1390 		if (noff < 0)
1391 			cerror("stack overflow");
1392 		SETOFF(noff, al);
1393 		off = -noff;
1394 	} else
1395 #endif
1396 	if (p->sclass == PARAM && (p->stype == CHAR || p->stype == UCHAR ||
1397 	    p->stype == SHORT || p->stype == USHORT || p->stype == BOOL)) {
1398 		off = upoff(SZINT, ALINT, &noff);
1399 #if TARGET_ENDIAN == TARGET_BE
1400 		off = noff - tsz;
1401 #endif
1402 	} else {
1403 		off = upoff(tsz, al, &noff);
1404 	}
1405 
1406 	if (p->sclass != REGISTER) {
1407 	/* in case we are allocating stack space for register arguments */
1408 		if (p->soffset == NOOFFSET)
1409 			p->soffset = off;
1410 		else if(off != p->soffset)
1411 			return(1);
1412 	}
1413 
1414 	*poff = noff;
1415 	return(0);
1416 }
1417 
1418 /*
1419  * Delay emission of code generated in argument headers.
1420  */
1421 static void
edelay(NODE * p)1422 edelay(NODE *p)
1423 {
1424 	if (blevel == 1) {
1425 		/* Delay until after declarations */
1426 		if (parlink == NULL)
1427 			parlink = p;
1428 		else
1429 			parlink = block(COMOP, parlink, p, 0, 0, 0);
1430 	} else
1431 		ecomp(p);
1432 }
1433 
1434 /*
1435  * Traverse through the array args, evaluate them and put the
1436  * resulting temp numbers in the dim fields.
1437  */
1438 static void
evalidx(struct symtab * sp)1439 evalidx(struct symtab *sp)
1440 {
1441 	union dimfun *df;
1442 	NODE *p;
1443 	TWORD t;
1444 	int astkp = 0;
1445 
1446 	if (arrstk[0] == NIL)
1447 		astkp++; /* for parameter arrays */
1448 
1449 	if (isdyn(sp))
1450 		sp->sflags |= SDYNARRAY;
1451 
1452 	df = sp->sdf;
1453 	for (t = sp->stype; t > BTMASK; t = DECREF(t)) {
1454 		if (!ISARY(t))
1455 			continue;
1456 		if (df->ddim == -1) {
1457 			p = tempnode(0, INT, 0, 0);
1458 			df->ddim = -regno(p);
1459 			edelay(buildtree(ASSIGN, p, arrstk[astkp++]));
1460 		}
1461 		df++;
1462 	}
1463 	arrstkp = 0;
1464 }
1465 
1466 /*
1467  * Return 1 if dynamic array, 0 otherwise.
1468  */
1469 int
isdyn(struct symtab * sp)1470 isdyn(struct symtab *sp)
1471 {
1472 	union dimfun *df = sp->sdf;
1473 	TWORD t;
1474 
1475 	for (t = sp->stype; t > BTMASK; t = DECREF(t)) {
1476 		if (!ISARY(t))
1477 			return 0;
1478 		if (df->ddim < 0 && df->ddim != NOOFFSET)
1479 			return 1;
1480 		df++;
1481 	}
1482 	return 0;
1483 }
1484 
1485 /*
1486  * Allocate space on the stack for dynamic arrays (or at least keep track
1487  * of the index).
1488  * Strategy is as follows:
1489  * - first entry is a pointer to the dynamic datatype.
1490  * - if it's a one-dimensional array this will be the only entry used.
1491  * - if it's a multi-dimensional array the following (numdim-1) integers
1492  *   will contain the sizes to multiply the indexes with.
1493  * - code to write the dimension sizes this will be generated here.
1494  * - code to allocate space on the stack will be generated here.
1495  */
1496 static void
dynalloc(struct symtab * p,int * poff)1497 dynalloc(struct symtab *p, int *poff)
1498 {
1499 	union dimfun *df;
1500 	NODE *n, *tn, *pol;
1501 	TWORD t;
1502 
1503 	/*
1504 	 * The pointer to the array is not necessarily stored in a
1505 	 * TEMP node, but if it is, its number is in the soffset field;
1506 	 */
1507 	t = p->stype;
1508 	p->sflags |= STNODE;
1509 	p->stype = INCREF(p->stype); /* Make this an indirect pointer */
1510 	tn = tempnode(0, p->stype, p->sdf, p->sap);
1511 	p->soffset = regno(tn);
1512 
1513 	df = p->sdf;
1514 
1515 	pol = bcon(1);
1516 	for (; t > BTMASK; t = DECREF(t)) {
1517 		if (!ISARY(t))
1518 			break;
1519 		if (df->ddim < 0)
1520 			n = tempnode(-df->ddim, INT, 0, 0);
1521 		else
1522 			n = bcon(df->ddim);
1523 
1524 		pol = buildtree(MUL, pol, n);
1525 		df++;
1526 	}
1527 	/* Create stack gap */
1528 	spalloc(tn, pol, tsize(t, 0, p->sap));
1529 }
1530 
1531 /*
1532  * allocate a field of width w
1533  * new is 0 if new entry, 1 if redefinition, -1 if alignment
1534  */
1535 int
falloc(struct symtab * p,int w,NODE * pty)1536 falloc(struct symtab *p, int w, NODE *pty)
1537 {
1538 	TWORD otype, type;
1539 	int al,sz;
1540 
1541 	otype = type = p ? p->stype : pty->n_type;
1542 
1543 	if (type == BOOL)
1544 		type = BOOL_TYPE;
1545 	if (!ISINTEGER(type)) {
1546 		uerror("illegal field type");
1547 		type = INT;
1548 	}
1549 
1550 	al = talign(type, NULL);
1551 	sz = tsize(type, NULL, NULL);
1552 
1553 	if (w > sz) {
1554 		uerror("field too big");
1555 		w = sz;
1556 	}
1557 
1558 	if (w == 0) { /* align only */
1559 		SETOFF(rpole->rstr, al);
1560 		if (p != NULL)
1561 			uerror("zero size field");
1562 		return(0);
1563 	}
1564 
1565 	if (rpole->rstr%al + w > sz)
1566 		SETOFF(rpole->rstr, al);
1567 	if (p == NULL) {
1568 		rpole->rstr += w;  /* we know it will fit */
1569 		return(0);
1570 	}
1571 
1572 	/* establish the field */
1573 
1574 	p->soffset = rpole->rstr;
1575 	rpole->rstr += w;
1576 	p->stype = otype;
1577 	fldty(p);
1578 	return(0);
1579 }
1580 
1581 /*
1582  * Check if this symbol should be a common or must be handled in data seg.
1583  */
1584 static void
commchk(struct symtab * sp)1585 commchk(struct symtab *sp)
1586 {
1587 	if ((sp->sflags & STLS)
1588 #ifdef GCC_COMPAT
1589 		|| attr_find(sp->sap, GCC_ATYP_SECTION)
1590 #endif
1591 	    ) {
1592 		/* TLS handled in data segment */
1593 		if (sp->sclass == EXTERN)
1594 			sp->sclass = EXTDEF;
1595 		beginit(sp);
1596 		endinit(1);
1597 	} else {
1598 		symdirec(sp);
1599 		defzero(sp);
1600 	}
1601 }
1602 
1603 void
nidcl(NODE * p,int class)1604 nidcl(NODE *p, int class)
1605 {
1606 	nidcl2(p, class, 0);
1607 }
1608 
1609 /*
1610  * handle unitialized declarations assumed to be not functions:
1611  * int a;
1612  * extern int a;
1613  * static int a;
1614  */
1615 void
nidcl2(NODE * p,int class,char * astr)1616 nidcl2(NODE *p, int class, char *astr)
1617 {
1618 	struct symtab *sp;
1619 	int commflag = 0;
1620 
1621 	/* compute class */
1622 	if (class == SNULL) {
1623 		if (blevel > 1)
1624 			class = AUTO;
1625 		else if (blevel != 0 || rpole)
1626 			cerror( "nidcl error" );
1627 		else /* blevel = 0 */
1628 			commflag = 1, class = EXTERN;
1629 	}
1630 
1631 	defid2(p, class, astr);
1632 
1633 	sp = p->n_sp;
1634 	/* check if forward decl */
1635 	if (ISARY(sp->stype) && sp->sdf->ddim == NOOFFSET)
1636 		return;
1637 
1638 	if (sp->sflags & SASG)
1639 		return; /* already initialized */
1640 
1641 	switch (class) {
1642 	case EXTDEF:
1643 		/* simulate initialization by 0 */
1644 		simpleinit(p->n_sp, bcon(0));
1645 		break;
1646 	case EXTERN:
1647 		if (commflag)
1648 			lcommadd(p->n_sp);
1649 		else
1650 			extdec(p->n_sp);
1651 		break;
1652 	case STATIC:
1653 		if (blevel == 0)
1654 			lcommadd(p->n_sp);
1655 		else
1656 			commchk(p->n_sp);
1657 		break;
1658 	}
1659 }
1660 
1661 struct lcd {
1662 	SLIST_ENTRY(lcd) next;
1663 	struct symtab *sp;
1664 };
1665 
1666 static SLIST_HEAD(, lcd) lhead = { NULL, &lhead.q_forw};
1667 
1668 /*
1669  * Add a local common statement to the printout list.
1670  */
1671 void
lcommadd(struct symtab * sp)1672 lcommadd(struct symtab *sp)
1673 {
1674 	struct lcd *lc, *lcp;
1675 
1676 	lcp = NULL;
1677 	SLIST_FOREACH(lc, &lhead, next) {
1678 		if (lc->sp == sp)
1679 			return; /* already exists */
1680 		if (lc->sp == NULL && lcp == NULL)
1681 			lcp = lc;
1682 	}
1683 	if (lcp == NULL) {
1684 		lc = permalloc(sizeof(struct lcd));
1685 		lc->sp = sp;
1686 		SLIST_INSERT_LAST(&lhead, lc, next);
1687 	} else
1688 		lcp->sp = sp;
1689 }
1690 
1691 /*
1692  * Delete a local common statement.
1693  */
1694 void
lcommdel(struct symtab * sp)1695 lcommdel(struct symtab *sp)
1696 {
1697 	struct lcd *lc;
1698 
1699 	SLIST_FOREACH(lc, &lhead, next) {
1700 		if (lc->sp == sp) {
1701 			lc->sp = NULL;
1702 			return;
1703 		}
1704 	}
1705 }
1706 
1707 /*
1708  * Print out the remaining common statements.
1709  */
1710 void
lcommprint(void)1711 lcommprint(void)
1712 {
1713 	struct lcd *lc;
1714 
1715 	SLIST_FOREACH(lc, &lhead, next) {
1716 		if (lc->sp != NULL)
1717 			commchk(lc->sp);
1718 	}
1719 }
1720 
1721 /*
1722  * Merge given types to a single node.
1723  * Any type can end up here.
1724  * p is the old node, q is the old (if any).
1725  * CLASS is AUTO, EXTERN, REGISTER, STATIC or TYPEDEF.
1726  * QUALIFIER is VOL or CON
1727  * TYPE is CHAR, SHORT, INT, LONG, SIGNED, UNSIGNED, VOID, BOOL, FLOAT,
1728  * 	DOUBLE, STRTY, UNIONTY.
1729  */
1730 struct typctx {
1731 	int class, qual, sig, uns, cmplx, imag, err;
1732 	TWORD type;
1733 	NODE *saved;
1734 	struct attr *pre, *post;
1735 };
1736 
1737 static void
typwalk(NODE * p,void * arg)1738 typwalk(NODE *p, void *arg)
1739 {
1740 	struct typctx *tc = arg;
1741 
1742 #define	cmop(x,y) block(CM, x, y, INT, 0, 0)
1743 	switch (p->n_op) {
1744 	case ATTRIB:
1745 #ifdef GCC_COMPAT
1746 		if (tc->saved && (tc->saved->n_qual & 1)) {
1747 			tc->post = attr_add(tc->post,gcc_attr_parse(p->n_left));
1748 		} else {
1749 			tc->pre = attr_add(tc->pre, gcc_attr_parse(p->n_left));
1750 		}
1751 		p->n_left = bcon(0); /* For tfree() */
1752 #else
1753 		uerror("gcc type attribute used");
1754 #endif
1755 		break;
1756 	case CLASS:
1757 		if (p->n_type == 0)
1758 			break;	/* inline hack */
1759 		if (tc->class)
1760 			tc->err = 1; /* max 1 class */
1761 		tc->class = p->n_type;
1762 		break;
1763 
1764 	case QUALIFIER:
1765 		if (p->n_qual == 0 &&
1766 		    ((tc->saved && !ISPTR(tc->saved->n_type)) ||
1767 		    (tc->saved == 0)))
1768 			uerror("invalid use of 'restrict'");
1769 		tc->qual |= p->n_qual >> TSHIFT;
1770 		break;
1771 
1772 	case TYPE:
1773 		if (p->n_sp != NULL || ISSOU(p->n_type)) {
1774 			/* typedef, enum or struct/union */
1775 			if (tc->saved || tc->type)
1776 				tc->err = 1;
1777 #ifdef GCC_COMPAT
1778 			if (ISSOU(p->n_type) && p->n_left) {
1779 				if (tc->post)
1780 					cerror("typwalk");
1781 				tc->post = gcc_attr_parse(p->n_left);
1782 			}
1783 #endif
1784 			tc->saved = ccopy(p);
1785 			break;
1786 		}
1787 
1788 		switch (p->n_type) {
1789 		case BOOL:
1790 		case CHAR:
1791 		case FLOAT:
1792 		case VOID:
1793 			if (tc->type)
1794 				tc->err = 1;
1795 			tc->type = p->n_type;
1796 			break;
1797 		case DOUBLE:
1798 			if (tc->type == 0)
1799 				tc->type = DOUBLE;
1800 			else if (tc->type == LONG)
1801 				tc->type = LDOUBLE;
1802 			else
1803 				tc->err = 1;
1804 			break;
1805 		case SHORT:
1806 			if (tc->type == 0 || tc->type == INT)
1807 				tc->type = SHORT;
1808 			else
1809 				tc->err = 1;
1810 			break;
1811 		case INT:
1812 			if (tc->type == SHORT || tc->type == LONG ||
1813 			    tc->type == LONGLONG)
1814 				break;
1815 			else if (tc->type == 0)
1816 				tc->type = INT;
1817 			else
1818 				tc->err = 1;
1819 			break;
1820 		case LONG:
1821 			if (tc->type == 0)
1822 				tc->type = LONG;
1823 			else if (tc->type == INT)
1824 				break;
1825 			else if (tc->type == LONG)
1826 				tc->type = LONGLONG;
1827 			else if (tc->type == DOUBLE)
1828 				tc->type = LDOUBLE;
1829 			else
1830 				tc->err = 1;
1831 			break;
1832 		case SIGNED:
1833 			if (tc->sig || tc->uns)
1834 				tc->err = 1;
1835 			tc->sig = 1;
1836 			break;
1837 		case UNSIGNED:
1838 			if (tc->sig || tc->uns)
1839 				tc->err = 1;
1840 			tc->uns = 1;
1841 			break;
1842 		case COMPLEX:
1843 			tc->cmplx = 1;
1844 			break;
1845 		case IMAG:
1846 			tc->imag = 1;
1847 			break;
1848 		default:
1849 			cerror("typwalk");
1850 		}
1851 	}
1852 
1853 }
1854 
1855 NODE *
typenode(NODE * p)1856 typenode(NODE *p)
1857 {
1858 	struct symtab *sp;
1859 	struct typctx tc;
1860 	NODE *q;
1861 	char *c;
1862 
1863 	memset(&tc, 0, sizeof(struct typctx));
1864 
1865 	flist(p, typwalk, &tc);
1866 	tfree(p);
1867 
1868 	if (tc.err)
1869 		goto bad;
1870 
1871 	if (tc.cmplx || tc.imag) {
1872 		if (tc.type == 0)
1873 			tc.type = DOUBLE;
1874 		if ((tc.cmplx && tc.imag) || tc.sig || tc.uns ||
1875 		    !ISFTY(tc.type))
1876 			goto bad;
1877 		if (tc.cmplx) {
1878 			c = tc.type == DOUBLE ? "0d" :
1879 			    tc.type == FLOAT ? "0f" : "0l";
1880 			sp = lookup(addname(c), 0);
1881 			tc.type = STRTY;
1882 			tc.saved = mkty(tc.type, sp->sdf, sp->sap);
1883 			tc.saved->n_sp = sp;
1884 			tc.type = 0;
1885 		} else
1886 			tc.type += (FIMAG-FLOAT);
1887 	}
1888 
1889 	if (tc.saved && tc.type)
1890 		goto bad;
1891 	if (tc.sig || tc.uns) {
1892 		if (tc.type == 0)
1893 			tc.type = tc.sig ? INT : UNSIGNED;
1894 		if (tc.type > ULONGLONG)
1895 			goto bad;
1896 		if (tc.uns)
1897 			tc.type = ENUNSIGN(tc.type);
1898 	}
1899 
1900 	if (xuchar && tc.type == CHAR && tc.sig == 0)
1901 		tc.type = UCHAR;
1902 
1903 #ifdef GCC_COMPAT
1904 	if (pragma_packed) {
1905 		q = bdty(CALL, bdty(NAME, "packed"), bcon(pragma_packed));
1906 		tc.post = attr_add(tc.post, gcc_attr_parse(q));
1907 	}
1908 	if (pragma_aligned) {
1909 		/* Deal with relevant pragmas */
1910 		q = bdty(CALL, bdty(NAME, "aligned"), bcon(pragma_aligned));
1911 		tc.post = attr_add(tc.post, gcc_attr_parse(q));
1912 	}
1913 	pragma_aligned = pragma_packed = 0;
1914 #endif
1915 	if ((q = tc.saved) == NULL) {
1916 		TWORD t;
1917 		if ((t = BTYPE(tc.type)) > LDOUBLE && t != VOID &&
1918 		    t != BOOL && !(t >= FIMAG && t <= LIMAG))
1919 			cerror("typenode2 t %x", tc.type);
1920 		if (t == UNDEF) {
1921 			t = INT;
1922 			MODTYPE(tc.type, INT);
1923 		}
1924 		q =  mkty(tc.type, 0, 0);
1925 	}
1926 	q->n_ap = attr_add(q->n_ap, tc.post);
1927 	q->n_qual = tc.qual;
1928 	q->n_lval = tc.class;
1929 #ifdef GCC_COMPAT
1930 	if (tc.post) {
1931 		/* Can only occur for TYPEDEF, STRUCT or UNION */
1932 		if (tc.saved == NULL)
1933 			cerror("typenode");
1934 		if (tc.saved->n_sp) /* trailer attributes for structs */
1935 			tc.saved->n_sp->sap = q->n_ap;
1936 	}
1937 	if (tc.pre)
1938 		q->n_ap = attr_add(q->n_ap, tc.pre);
1939 	gcc_tcattrfix(q);
1940 #endif
1941 	return q;
1942 
1943 bad:	uerror("illegal type combination");
1944 	return mkty(INT, 0, 0);
1945 }
1946 
1947 struct tylnk {
1948 	struct tylnk *next;
1949 	union dimfun df;
1950 };
1951 
1952 /*
1953  * Retrieve all CM-separated argument types, sizes and dimensions and
1954  * put them in an array.
1955  * XXX - can only check first type level, side effects?
1956  */
1957 static union arglist *
arglist(NODE * n)1958 arglist(NODE *n)
1959 {
1960 	union arglist *al;
1961 	NODE *w = n, **ap;
1962 	int num, cnt, i, j, k;
1963 	TWORD ty;
1964 
1965 #ifdef PCC_DEBUG
1966 	if (pdebug) {
1967 		printf("arglist %p\n", n);
1968 		fwalk(n, eprint, 0);
1969 	}
1970 #endif
1971 	/* First: how much to allocate */
1972 	for (num = cnt = 0, w = n; w->n_op == CM; w = w->n_left) {
1973 		cnt++;	/* Number of levels */
1974 		num++;	/* At least one per step */
1975 		if (w->n_right->n_op == ELLIPSIS)
1976 			continue;
1977 		ty = w->n_right->n_type;
1978 		if (ty == ENUMTY) {
1979 			uerror("arg %d enum undeclared", cnt);
1980 			ty = w->n_right->n_type = INT;
1981 		}
1982 		if (BTYPE(ty) == STRTY || BTYPE(ty) == UNIONTY)
1983 			num++;
1984 		while (!ISFTN(ty) && !ISARY(ty) && ty > BTMASK)
1985 			ty = DECREF(ty);
1986 		if (ty > BTMASK)
1987 			num++;
1988 	}
1989 	cnt++;
1990 	ty = w->n_type;
1991 	if (ty == ENUMTY) {
1992 		uerror("arg %d enum undeclared", cnt);
1993 		ty = w->n_type = INT;
1994 	}
1995 	if (BTYPE(ty) == STRTY || BTYPE(ty) == UNIONTY)
1996 		num++;
1997 	while (!ISFTN(ty) && !ISARY(ty) && ty > BTMASK)
1998 		ty = DECREF(ty);
1999 	if (ty > BTMASK)
2000 		num++;
2001 	num += 2; /* TEND + last arg type */
2002 
2003 	/* Second: Create list to work on */
2004 	ap = tmpalloc(sizeof(NODE *) * cnt);
2005 	al = permalloc(sizeof(union arglist) * num);
2006 	arglistcnt += num;
2007 
2008 	for (w = n, i = 0; w->n_op == CM; w = w->n_left)
2009 		ap[i++] = w->n_right;
2010 	ap[i] = w;
2011 
2012 	/* Third: Create actual arg list */
2013 	for (k = 0, j = i; j >= 0; j--) {
2014 		if (ap[j]->n_op == ELLIPSIS) {
2015 			al[k++].type = TELLIPSIS;
2016 			ap[j]->n_op = ICON; /* for tfree() */
2017 			continue;
2018 		}
2019 		/* Convert arrays to pointers */
2020 		if (ISARY(ap[j]->n_type)) {
2021 			ap[j]->n_type += (PTR-ARY);
2022 			ap[j]->n_df++;
2023 		}
2024 		/* Convert (silently) functions to pointers */
2025 		if (ISFTN(ap[j]->n_type))
2026 			ap[j]->n_type = INCREF(ap[j]->n_type);
2027 		ty = ap[j]->n_type;
2028 #ifdef GCC_COMPAT
2029 		if (ty == UNIONTY &&
2030 		    attr_find(ap[j]->n_ap, GCC_ATYP_TRANSP_UNION)){
2031 			/* transparent unions must have compatible types
2032 			 * shortcut here: if pointers, set void *,
2033 			 * otherwise btype.
2034 			 */
2035 			struct symtab *sp = strmemb(ap[j]->n_ap);
2036 			ty = ISPTR(sp->stype) ? PTR|VOID : sp->stype;
2037 		}
2038 #endif
2039 		al[k++].type = ty;
2040 		if (BTYPE(ty) == STRTY || BTYPE(ty) == UNIONTY)
2041 			al[k++].sap = ap[j]->n_ap;
2042 		while (!ISFTN(ty) && !ISARY(ty) && ty > BTMASK)
2043 			ty = DECREF(ty);
2044 		if (ty > BTMASK)
2045 			al[k++].df = ap[j]->n_df;
2046 	}
2047 	al[k++].type = TNULL;
2048 	if (k > num)
2049 		cerror("arglist: k%d > num%d", k, num);
2050 	tfree(n);
2051 #ifdef PCC_DEBUG
2052 	if (pdebug)
2053 		alprint(al, 0);
2054 #endif
2055 	return al;
2056 }
2057 
2058 static void
tylkadd(union dimfun dim,struct tylnk ** tylkp,int * ntdim)2059 tylkadd(union dimfun dim, struct tylnk **tylkp, int *ntdim)
2060 {
2061 	(*tylkp)->next = tmpalloc(sizeof(struct tylnk));
2062 	*tylkp = (*tylkp)->next;
2063 	(*tylkp)->next = NULL;
2064 	(*tylkp)->df = dim;
2065 	(*ntdim)++;
2066 }
2067 
2068 /*
2069  * build a type, and stash away dimensions,
2070  * from a parse tree of the declaration
2071  * the type is build top down, the dimensions bottom up
2072  */
2073 static void
tyreduce(NODE * p,struct tylnk ** tylkp,int * ntdim)2074 tyreduce(NODE *p, struct tylnk **tylkp, int *ntdim)
2075 {
2076 	union dimfun dim;
2077 	NODE *r = NULL;
2078 	int o;
2079 	TWORD t, q;
2080 
2081 	o = p->n_op;
2082 	if (o == NAME) {
2083 		p->n_qual = DECQAL(p->n_qual);
2084 		return;
2085 	}
2086 
2087 	t = INCREF(p->n_type);
2088 	q = p->n_qual;
2089 	switch (o) {
2090 	case CALL:
2091 		t += (FTN-PTR);
2092 		dim.dfun = arglist(p->n_right);
2093 		break;
2094 	case UCALL:
2095 		t += (FTN-PTR);
2096 		dim.dfun = NULL;
2097 		break;
2098 	case LB:
2099 		t += (ARY-PTR);
2100 		if (p->n_right->n_op != ICON) {
2101 			r = p->n_right;
2102 			o = RB;
2103 		} else {
2104 			dim.ddim = (int)p->n_right->n_lval;
2105 			nfree(p->n_right);
2106 #ifdef notdef
2107 	/* XXX - check dimensions at usage time */
2108 			if (dim.ddim == NOOFFSET && p->n_left->n_op == LB)
2109 				uerror("null dimension");
2110 #endif
2111 		}
2112 		break;
2113 	}
2114 
2115 	p->n_left->n_type = t;
2116 	p->n_left->n_qual = INCQAL(q) | p->n_left->n_qual;
2117 	tyreduce(p->n_left, tylkp, ntdim);
2118 
2119 	if (o == LB || o == UCALL || o == CALL)
2120 		tylkadd(dim, tylkp, ntdim);
2121 	if (o == RB) {
2122 		dim.ddim = -1;
2123 		tylkadd(dim, tylkp, ntdim);
2124 		arrstk[arrstkp++] = r;
2125 	}
2126 
2127 	p->n_sp = p->n_left->n_sp;
2128 	p->n_type = p->n_left->n_type;
2129 	p->n_qual = p->n_left->n_qual;
2130 }
2131 
2132 /*
2133  * merge type typ with identifier idp.
2134  * idp is returned as a NAME node with correct types,
2135  * typ is untouched since multiple declarations uses it.
2136  * typ has type attributes, idp can never carry such attributes
2137  * so on return just a pointer to the typ attributes is returned.
2138  */
2139 NODE *
tymerge(NODE * typ,NODE * idp)2140 tymerge(NODE *typ, NODE *idp)
2141 {
2142 	TWORD t;
2143 	NODE *p;
2144 	union dimfun *j;
2145 	struct tylnk *base, tylnk, *tylkp;
2146 	struct attr *bap;
2147 	int ntdim, i;
2148 
2149 #ifdef PCC_DEBUG
2150 	if (ddebug > 2) {
2151 		printf("tymerge(%p,%p)\n", typ, idp);
2152 		fwalk(typ, eprint, 0);
2153 		fwalk(idp, eprint, 0);
2154 	}
2155 #endif
2156 
2157 	if (typ->n_op != TYPE)
2158 		cerror("tymerge: arg 1");
2159 
2160 	bap = typ->n_ap;
2161 
2162 	idp->n_type = typ->n_type;
2163 	idp->n_qual |= typ->n_qual;
2164 
2165 	tylkp = &tylnk;
2166 	tylkp->next = NULL;
2167 	ntdim = 0;
2168 
2169 	tyreduce(idp, &tylkp, &ntdim);
2170 
2171 	for (t = typ->n_type, j = typ->n_df; t&TMASK; t = DECREF(t))
2172 		if (ISARY(t) || ISFTN(t))
2173 			tylkadd(*j++, &tylkp, &ntdim);
2174 
2175 	if (ntdim) {
2176 		union dimfun *a = permalloc(sizeof(union dimfun) * ntdim);
2177 		dimfuncnt += ntdim;
2178 		for (i = 0, base = tylnk.next; base; base = base->next, i++)
2179 			a[i] = base->df;
2180 		idp->n_df = a;
2181 	} else
2182 		idp->n_df = NULL;
2183 
2184 	/* now idp is a single node: fix up type */
2185 	if ((t = ctype(idp->n_type)) != idp->n_type)
2186 		idp->n_type = t;
2187 
2188 	if (idp->n_op != NAME) {
2189 		for (p = idp->n_left; p->n_op != NAME; p = p->n_left)
2190 			nfree(p);
2191 		nfree(p);
2192 		idp->n_op = NAME;
2193 	}
2194 	/* carefully not destroy any type attributes */
2195 	if (idp->n_ap != NULL) {
2196 		struct attr *ap = idp->n_ap;
2197 		while (ap->next)
2198 			ap = ap->next;
2199 		ap->next = bap;
2200 	} else
2201 		idp->n_ap = bap;
2202 
2203 	return(idp);
2204 }
2205 
2206 static NODE *
argcast(NODE * p,TWORD t,union dimfun * d,struct attr * ap)2207 argcast(NODE *p, TWORD t, union dimfun *d, struct attr *ap)
2208 {
2209 	NODE *u, *r = talloc();
2210 
2211 	r->n_op = NAME;
2212 	r->n_type = t;
2213 	r->n_qual = 0; /* XXX */
2214 	r->n_df = d;
2215 	r->n_ap = ap;
2216 
2217 	u = buildtree(CAST, r, p);
2218 	nfree(u->n_left);
2219 	r = u->n_right;
2220 	nfree(u);
2221 	return r;
2222 }
2223 
2224 #ifdef PCC_DEBUG
2225 /*
2226  * Print a prototype.
2227  */
2228 static void
alprint(union arglist * al,int in)2229 alprint(union arglist *al, int in)
2230 {
2231 	TWORD t;
2232 	int i = 0, j;
2233 
2234 	for (; al->type != TNULL; al++) {
2235 		for (j = in; j > 0; j--)
2236 			printf("  ");
2237 		printf("arg %d: ", i++);
2238 		t = al->type;
2239 		tprint(t, 0);
2240 		while (t > BTMASK) {
2241 			if (ISARY(t)) {
2242 				al++;
2243 				printf(" dim %d ", al->df->ddim);
2244 			} else if (ISFTN(t)) {
2245 				al++;
2246 				if (al->df->dfun) {
2247 					printf("\n");
2248 					alprint(al->df->dfun, in+1);
2249 				}
2250 			}
2251 			t = DECREF(t);
2252 		}
2253 		if (ISSOU(t)) {
2254 			al++;
2255 			printf(" (size %d align %d)", (int)tsize(t, 0, al->sap),
2256 			    (int)talign(t, al->sap));
2257 		}
2258 		printf("\n");
2259 	}
2260 	if (in == 0)
2261 		printf("end arglist\n");
2262 }
2263 #endif
2264 
2265 int
suemeq(struct attr * s1,struct attr * s2)2266 suemeq(struct attr *s1, struct attr *s2)
2267 {
2268 
2269 	return (strmemb(s1) == strmemb(s2));
2270 }
2271 
2272 /*
2273  * Sanity-check old-style args.
2274  */
2275 static NODE *
oldarg(NODE * p)2276 oldarg(NODE *p)
2277 {
2278 	if (p->n_op == TYPE)
2279 		uerror("type is not an argument");
2280 	if (p->n_type == FLOAT)
2281 		return cast(p, DOUBLE, p->n_qual);
2282 	return p;
2283 }
2284 
2285 /*
2286  * Do prototype checking and add conversions before calling a function.
2287  * Argument f is function and a is a CM-separated list of arguments.
2288  * Returns a merged node (via buildtree() of function and arguments.
2289  */
2290 NODE *
doacall(struct symtab * sp,NODE * f,NODE * a)2291 doacall(struct symtab *sp, NODE *f, NODE *a)
2292 {
2293 	NODE *w, *r;
2294 	union arglist *al;
2295 	struct ap {
2296 		struct ap *next;
2297 		NODE *node;
2298 	} *at, *apole = NULL;
2299 	int argidx/* , hasarray = 0*/;
2300 	TWORD type, arrt;
2301 
2302 #ifdef PCC_DEBUG
2303 	if (ddebug) {
2304 		printf("doacall.\n");
2305 		fwalk(f, eprint, 0);
2306 		if (a)
2307 			fwalk(a, eprint, 0);
2308 	}
2309 #endif
2310 
2311 	/* First let MD code do something */
2312 	calldec(f, a);
2313 /* XXX XXX hack */
2314 	if ((f->n_op == CALL) &&
2315 	    f->n_left->n_op == ADDROF &&
2316 	    f->n_left->n_left->n_op == NAME &&
2317 	    (f->n_left->n_left->n_type & 0x7e0) == 0x4c0)
2318 		goto build;
2319 /* XXX XXX hack */
2320 
2321 	/* Check for undefined or late defined enums */
2322 	if (BTYPE(f->n_type) == ENUMTY) {
2323 		/* not-yet check if declared enum */
2324 		struct symtab *sq = strmemb(f->n_ap);
2325 		if (sq->stype != ENUMTY)
2326 			MODTYPE(f->n_type, sq->stype);
2327 		if (BTYPE(f->n_type) == ENUMTY)
2328 			uerror("enum %s not declared", sq->sname);
2329 	}
2330 
2331 	/*
2332 	 * Do some basic checks.
2333 	 */
2334 	if (f->n_df == NULL || (al = f->n_df[0].dfun) == NULL) {
2335 		/*
2336 		 * Handle non-prototype declarations.
2337 		 */
2338 		if (f->n_op == NAME && f->n_sp != NULL) {
2339 			if (strncmp(f->n_sp->sname, "__builtin", 9) != 0 &&
2340 			    (f->n_sp->sflags & SINSYS) == 0)
2341 				warner(Wmissing_prototypes, f->n_sp->sname);
2342 		} else
2343 			warner(Wmissing_prototypes, "<pointer>");
2344 
2345 		/* floats must be cast to double */
2346 		if (a == NULL)
2347 			goto build;
2348 		if (a->n_op != CM) {
2349 			a = oldarg(a);
2350 		} else {
2351 			for (w = a; w->n_left->n_op == CM; w = w->n_left)
2352 				w->n_right = oldarg(w->n_right);
2353 			w->n_left = oldarg(w->n_left);
2354 			w->n_right = oldarg(w->n_right);
2355 		}
2356 		goto build;
2357 	}
2358 	if (al->type == VOID) {
2359 		if (a != NULL)
2360 			uerror("function takes no arguments");
2361 		goto build; /* void function */
2362 	} else {
2363 		if (a == NULL) {
2364 			uerror("function needs arguments");
2365 			goto build;
2366 		}
2367 	}
2368 #ifdef PCC_DEBUG
2369 	if (pdebug) {
2370 		printf("arglist for %s\n",
2371 		    f->n_sp != NULL ? f->n_sp->sname : "function pointer");
2372 		alprint(al, 0);
2373 	}
2374 #endif
2375 
2376 	/*
2377 	 * Create a list of pointers to the nodes given as arg.
2378 	 */
2379 	for (w = a; w->n_op == CM; w = w->n_left) {
2380 		at = tmpalloc(sizeof(struct ap));
2381 		at->node = w->n_right;
2382 		at->next = apole;
2383 		apole = at;
2384 	}
2385 	at = tmpalloc(sizeof(struct ap));
2386 	at->node = w;
2387 	at->next = apole;
2388 	apole = at;
2389 
2390 	/*
2391 	 * Do the typechecking by walking up the list.
2392 	 */
2393 	argidx = 1;
2394 	while (al->type != TNULL) {
2395 		if (al->type == TELLIPSIS) {
2396 			/* convert the rest of float to double */
2397 			for (; apole; apole = apole->next) {
2398 				if (apole->node->n_type != FLOAT)
2399 					continue;
2400 				MKTY(apole->node, DOUBLE, 0, 0);
2401 			}
2402 			goto build;
2403 		}
2404 		if (apole == NULL) {
2405 			uerror("too few arguments to function");
2406 			goto build;
2407 		}
2408 /* al = prototyp, apole = argument till ftn */
2409 /* type = argumentets typ, arrt = prototypens typ */
2410 		type = apole->node->n_type;
2411 		arrt = al->type;
2412 #if 0
2413 		if ((hasarray = ISARY(arrt)))
2414 			arrt += (PTR-ARY);
2415 #endif
2416 		/* Taking addresses of arrays are meaningless in expressions */
2417 		/* but people tend to do that and also use in prototypes */
2418 		/* this is mostly a problem with typedefs */
2419 		if (ISARY(type)) {
2420 			if (ISPTR(arrt) && ISARY(DECREF(arrt)))
2421 				type = INCREF(type);
2422 			else
2423 				type += (PTR-ARY);
2424 		} else if (ISPTR(type) && !ISARY(DECREF(type)) &&
2425 		    ISPTR(arrt) && ISARY(DECREF(arrt))) {
2426 			type += (ARY-PTR);
2427 			type = INCREF(type);
2428 		}
2429 
2430 		/* Check structs */
2431 		if (type <= BTMASK && arrt <= BTMASK) {
2432 #ifndef NO_COMPLEX
2433 			if ((type != arrt) && (ANYCX(apole->node) ||
2434 			    (arrt == STRTY &&
2435 			    attr_find(al[1].sap, ATTR_COMPLEX)))) {
2436 				cxargfixup(apole->node, arrt, al[1].sap);
2437 			} else
2438 #endif
2439 			if (type != arrt) {
2440 				if (ISSOU(BTYPE(type)) || ISSOU(BTYPE(arrt))) {
2441 incomp:					uerror("incompatible types for arg %d",
2442 					    argidx);
2443 				} else {
2444 					MKTY(apole->node, arrt, 0, 0)
2445 				}
2446 #ifndef NO_COMPLEX
2447 			} else if (type == STRTY &&
2448 			    attr_find(apole->node->n_ap, ATTR_COMPLEX) &&
2449 			    attr_find(al[1].sap, ATTR_COMPLEX)) {
2450 				/* Both are complex */
2451 				if (strmemb(apole->node->n_ap)->stype !=
2452 				    strmemb(al[1].sap)->stype) {
2453 					/* must convert to correct type */
2454 					w = talloc();
2455 					*w = *apole->node;
2456 					w = mkcmplx(w,
2457 					    strmemb(al[1].sap)->stype);
2458 					*apole->node = *w;
2459 					nfree(w);
2460 				}
2461 				goto out;
2462 #endif
2463 			} else if (ISSOU(BTYPE(type))) {
2464 				if (!suemeq(apole->node->n_ap, al[1].sap))
2465 					goto incomp;
2466 			}
2467 			goto out;
2468 		}
2469 
2470 		/* XXX should (recusively) check return type and arg list of
2471 		   func ptr arg XXX */
2472 		if (ISFTN(DECREF(arrt)) && ISFTN(type))
2473 			type = INCREF(type);
2474 
2475 		/* Hereafter its only pointers (or arrays) left */
2476 		/* Check for struct/union intermixing with other types */
2477 		if (((type <= BTMASK) && ISSOU(BTYPE(type))) ||
2478 		    ((arrt <= BTMASK) && ISSOU(BTYPE(arrt))))
2479 			goto incomp;
2480 
2481 		/* Check for struct/union compatibility */
2482 		if (type == arrt) {
2483 			if (ISSOU(BTYPE(type))) {
2484 				if (suemeq(apole->node->n_ap, al[1].sap))
2485 					goto out;
2486 			} else
2487 				goto out;
2488 		}
2489 		if (BTYPE(arrt) == VOID && type > BTMASK)
2490 			goto skip; /* void *f = some pointer */
2491 		if (arrt > BTMASK && BTYPE(type) == VOID)
2492 			goto skip; /* some *f = void pointer */
2493 		if (apole->node->n_op == ICON && apole->node->n_lval == 0)
2494 			goto skip; /* Anything assigned a zero */
2495 
2496 		if ((type & ~BTMASK) == (arrt & ~BTMASK)) {
2497 			/* do not complain for pointers with signedness */
2498 			if ((DEUNSIGN(BTYPE(type)) == DEUNSIGN(BTYPE(arrt))) &&
2499 			    (BTYPE(type) != BTYPE(arrt))) {
2500 				warner(Wpointer_sign);
2501 				goto skip;
2502 			}
2503 		}
2504 
2505 		werror("implicit conversion of argument %d due to prototype",
2506 		    argidx);
2507 
2508 skip:		if (ISSOU(BTYPE(arrt))) {
2509 			MKTY(apole->node, arrt, 0, al[1].sap)
2510 		} else {
2511 			MKTY(apole->node, arrt, 0, 0)
2512 		}
2513 
2514 out:		al++;
2515 		if (ISSOU(BTYPE(arrt)))
2516 			al++;
2517 #if 0
2518 		while (arrt > BTMASK && !ISFTN(arrt))
2519 			arrt = DECREF(arrt);
2520 		if (ISFTN(arrt) || hasarray)
2521 			al++;
2522 #else
2523 		while (arrt > BTMASK) {
2524 			if (ISARY(arrt) || ISFTN(arrt)) {
2525 				al++;
2526 				break;
2527 			}
2528 			arrt = DECREF(arrt);
2529 		}
2530 #endif
2531 		apole = apole->next;
2532 		argidx++;
2533 	}
2534 	if (apole != NULL)
2535 		uerror("too many arguments to function");
2536 
2537 build:	if (sp != NULL && (sp->sflags & SINLINE) && (w = inlinetree(sp, f, a)))
2538 		return w;
2539 	return buildtree(a == NIL ? UCALL : CALL, f, a);
2540 }
2541 
2542 static int
chk2(TWORD type,union dimfun * dsym,union dimfun * ddef)2543 chk2(TWORD type, union dimfun *dsym, union dimfun *ddef)
2544 {
2545 	while (type > BTMASK) {
2546 		switch (type & TMASK) {
2547 		case ARY:
2548 			/* may be declared without dimension */
2549 			if (dsym->ddim == NOOFFSET)
2550 				dsym->ddim = ddef->ddim;
2551 			if (dsym->ddim < 0 && ddef->ddim < 0)
2552 				; /* dynamic arrays as arguments */
2553 			else if (ddef->ddim > 0 && dsym->ddim != ddef->ddim)
2554 				return 1;
2555 			dsym++, ddef++;
2556 			break;
2557 		case FTN:
2558 			/* old-style function headers with function pointers
2559 			 * will most likely not have a prototype.
2560 			 * This is not considered an error.  */
2561 			if (ddef->dfun == NULL) {
2562 #ifdef notyet
2563 				werror("declaration not a prototype");
2564 #endif
2565 			} else if (chkftn(dsym->dfun, ddef->dfun))
2566 				return 1;
2567 			dsym++, ddef++;
2568 			break;
2569 		}
2570 		type = DECREF(type);
2571 	}
2572 	return 0;
2573 }
2574 
2575 /*
2576  * Compare two function argument lists to see if they match.
2577  */
2578 int
chkftn(union arglist * usym,union arglist * udef)2579 chkftn(union arglist *usym, union arglist *udef)
2580 {
2581 	TWORD t2;
2582 	int ty, tyn;
2583 
2584 	if (usym == NULL)
2585 		return 0;
2586 	if (cftnsp != NULL && udef == NULL && usym->type == VOID)
2587 		return 0; /* foo() { function with foo(void); prototype */
2588 	if (udef == NULL && usym->type != TNULL)
2589 		return 1;
2590 	while (usym->type != TNULL) {
2591 		if (usym->type == udef->type)
2592 			goto done;
2593 		/*
2594 		 * If an old-style declaration, then all types smaller than
2595 		 * int are given as int parameters.
2596 		 */
2597 		if (intcompare) {
2598 			ty = BTYPE(usym->type);
2599 			tyn = BTYPE(udef->type);
2600 			if (ty == tyn || ty != INT)
2601 				return 1;
2602 			if (tyn == CHAR || tyn == UCHAR ||
2603 			    tyn == SHORT || tyn == USHORT)
2604 				goto done;
2605 			return 1;
2606 		} else
2607 			return 1;
2608 
2609 done:		ty = BTYPE(usym->type);
2610 		t2 = usym->type;
2611 		if (ISSOU(ty)) {
2612 			usym++, udef++;
2613 			if (suemeq(usym->sap, udef->sap) == 0)
2614 				return 1;
2615 		}
2616 
2617 		while (!ISFTN(t2) && !ISARY(t2) && t2 > BTMASK)
2618 			t2 = DECREF(t2);
2619 		if (t2 > BTMASK) {
2620 			usym++, udef++;
2621 			if (chk2(t2, usym->df, udef->df))
2622 				return 1;
2623 		}
2624 		usym++, udef++;
2625 	}
2626 	if (usym->type != udef->type)
2627 		return 1;
2628 	return 0;
2629 }
2630 
2631 void
fixtype(NODE * p,int class)2632 fixtype(NODE *p, int class)
2633 {
2634 	unsigned int t, type;
2635 	int mod1, mod2;
2636 	/* fix up the types, and check for legality */
2637 
2638 	/* forward declared enums */
2639 	if (BTYPE(p->n_sp->stype) == ENUMTY) {
2640 		MODTYPE(p->n_sp->stype, strmemb(p->n_sp->sap)->stype);
2641 	}
2642 
2643 	if( (type = p->n_type) == UNDEF ) return;
2644 	if ((mod2 = (type&TMASK))) {
2645 		t = DECREF(type);
2646 		while( mod1=mod2, mod2 = (t&TMASK) ){
2647 			if( mod1 == ARY && mod2 == FTN ){
2648 				uerror( "array of functions is illegal" );
2649 				type = 0;
2650 				}
2651 			else if( mod1 == FTN && ( mod2 == ARY || mod2 == FTN ) ){
2652 				uerror( "function returns illegal type" );
2653 				type = 0;
2654 				}
2655 			t = DECREF(t);
2656 			}
2657 		}
2658 
2659 	/* detect function arguments, watching out for structure declarations */
2660 	if (rpole && ISFTN(type)) {
2661 		uerror("function illegal in structure or union");
2662 		type = INCREF(type);
2663 	}
2664 	p->n_type = type;
2665 }
2666 
2667 /*
2668  * give undefined version of class
2669  */
2670 int
uclass(int class)2671 uclass(int class)
2672 {
2673 	if (class == SNULL)
2674 		return(EXTERN);
2675 	else if (class == STATIC)
2676 		return(USTATIC);
2677 	else
2678 		return(class);
2679 }
2680 
2681 int
fixclass(int class,TWORD type)2682 fixclass(int class, TWORD type)
2683 {
2684 	extern int fun_inline;
2685 
2686 	/* first, fix null class */
2687 	if (class == SNULL) {
2688 		if (fun_inline && ISFTN(type))
2689 			return SNULL;
2690 		if (rpole)
2691 			cerror("field8");
2692 		else if (blevel == 0)
2693 			class = EXTDEF;
2694 		else
2695 			class = AUTO;
2696 	}
2697 
2698 	/* now, do general checking */
2699 
2700 	if( ISFTN( type ) ){
2701 		switch( class ) {
2702 		default:
2703 			uerror( "function has illegal storage class" );
2704 		case AUTO:
2705 			class = EXTERN;
2706 		case EXTERN:
2707 		case EXTDEF:
2708 		case TYPEDEF:
2709 		case STATIC:
2710 		case USTATIC:
2711 			;
2712 			}
2713 		}
2714 
2715 	if (class & FIELD) {
2716 		cerror("field3");
2717 	}
2718 
2719 	switch (class) {
2720 
2721 	case MOS:
2722 	case MOU:
2723 		cerror("field4");
2724 
2725 	case REGISTER:
2726 		if (blevel == 0)
2727 			uerror("illegal register declaration");
2728 		if (blevel == 1)
2729 			return(PARAM);
2730 		else
2731 			return(REGISTER);
2732 
2733 	case AUTO:
2734 		if( blevel < 2 ) uerror( "illegal ULABEL class" );
2735 		return( class );
2736 
2737 	case EXTERN:
2738 	case STATIC:
2739 	case EXTDEF:
2740 	case TYPEDEF:
2741 	case USTATIC:
2742 	case PARAM:
2743 		return( class );
2744 
2745 	default:
2746 		cerror( "illegal class: %d", class );
2747 		/* NOTREACHED */
2748 
2749 	}
2750 	return 0; /* XXX */
2751 }
2752 
2753 /*
2754  * Generates a goto statement; sets up label number etc.
2755  */
2756 void
gotolabel(char * name)2757 gotolabel(char *name)
2758 {
2759 	struct symtab *s = lookup(name, SLBLNAME);
2760 
2761 	if (s->soffset == 0) {
2762 		s->soffset = -getlab();
2763 		s->sclass = STATIC;
2764 	}
2765 	branch(s->soffset < 0 ? -s->soffset : s->soffset);
2766 }
2767 
2768 /*
2769  * Sets a label for gotos.
2770  */
2771 void
deflabel(char * name,NODE * p)2772 deflabel(char *name, NODE *p)
2773 {
2774 	struct symtab *s = lookup(name, SLBLNAME);
2775 
2776 #ifdef GCC_COMPAT
2777 	s->sap = gcc_attr_parse(p);
2778 #endif
2779 	if (s->soffset > 0)
2780 		uerror("label '%s' redefined", name);
2781 	if (s->soffset == 0) {
2782 		s->soffset = getlab();
2783 		s->sclass = STATIC;
2784 	}
2785 	if (s->soffset < 0)
2786 		s->soffset = -s->soffset;
2787 	plabel( s->soffset);
2788 }
2789 
2790 struct symtab *
getsymtab(char * name,int flags)2791 getsymtab(char *name, int flags)
2792 {
2793 	struct symtab *s;
2794 
2795 	if (flags & STEMP) {
2796 		s = tmpalloc(sizeof(struct symtab));
2797 	} else {
2798 		s = permalloc(sizeof(struct symtab));
2799 		symtabcnt++;
2800 	}
2801 	s->sname = name;
2802 	s->soname = NULL;
2803 	s->snext = NULL;
2804 	s->stype = UNDEF;
2805 	s->squal = 0;
2806 	s->sclass = SNULL;
2807 	s->sflags = (short)(flags & SMASK);
2808 	s->soffset = 0;
2809 	s->slevel = (char)blevel;
2810 	s->sdf = NULL;
2811 	s->sap = NULL;
2812 	return s;
2813 }
2814 
2815 int
fldchk(int sz)2816 fldchk(int sz)
2817 {
2818 	if (rpole->rsou != STNAME && rpole->rsou != UNAME)
2819 		uerror("field outside of structure");
2820 	if (sz < 0 || sz >= FIELD) {
2821 		uerror("illegal field size");
2822 		return 1;
2823 	}
2824 	return 0;
2825 }
2826 
2827 #ifdef PCC_DEBUG
2828 static char *
2829 ccnames[] = { /* names of storage classes */
2830 	"SNULL",
2831 	"AUTO",
2832 	"EXTERN",
2833 	"STATIC",
2834 	"REGISTER",
2835 	"EXTDEF",
2836 	"LABEL",
2837 	"ULABEL",
2838 	"MOS",
2839 	"PARAM",
2840 	"STNAME",
2841 	"MOU",
2842 	"UNAME",
2843 	"TYPEDEF",
2844 	"FORTRAN",
2845 	"ENAME",
2846 	"MOE",
2847 	"UFORTRAN",
2848 	"USTATIC",
2849 	};
2850 
2851 char *
scnames(int c)2852 scnames(int c)
2853 {
2854 	/* return the name for storage class c */
2855 	static char buf[12];
2856 	if( c&FIELD ){
2857 		snprintf( buf, sizeof(buf), "FIELD[%d]", c&FLDSIZ );
2858 		return( buf );
2859 		}
2860 	return( ccnames[c] );
2861 	}
2862 #endif
2863 
2864 #if 0
2865 static char *stack_chk_fail = "__stack_smash_handler";
2866 static char *stack_chk_guard = "__guard";
2867 #else
2868 static char *stack_chk_fail = "__stack_chk_fail";
2869 static char *stack_chk_guard = "__stack_chk_guard";
2870 #endif
2871 static char *stack_chk_canary = "__stack_chk_canary";
2872 
2873 void
sspinit(void)2874 sspinit(void)
2875 {
2876 	NODE *p;
2877 
2878 	p = block(NAME, NIL, NIL, FTN+VOID, 0, 0);
2879 	p->n_sp = lookup(stack_chk_fail, SNORMAL);
2880 	defid(p, EXTERN);
2881 	nfree(p);
2882 
2883 	p = block(NAME, NIL, NIL, INT, 0, 0);
2884 	p->n_sp = lookup(stack_chk_guard, SNORMAL);
2885 	defid(p, EXTERN);
2886 	nfree(p);
2887 }
2888 
2889 void
sspstart(void)2890 sspstart(void)
2891 {
2892 	NODE *p, *q;
2893 
2894 	q = block(NAME, NIL, NIL, INT, 0, 0);
2895  	q->n_sp = lookup(stack_chk_guard, SNORMAL);
2896 	q = clocal(q);
2897 
2898 	p = block(REG, NIL, NIL, INCREF(INT), 0, 0);
2899 	p->n_lval = 0;
2900 	p->n_rval = FPREG;
2901 	p = cast(p, INT, 0);
2902 	q = buildtree(ER, p, q);
2903 
2904 	p = block(NAME, NIL, NIL, INT, 0, 0);
2905 	p->n_qual = VOL >> TSHIFT;
2906 	p->n_sp = lookup(stack_chk_canary, SNORMAL);
2907 	defid(p, AUTO);
2908 	p = clocal(p);
2909 	ecomp(buildtree(ASSIGN, p, q));
2910 }
2911 
2912 void
sspend(void)2913 sspend(void)
2914 {
2915 	NODE *p, *q;
2916 	TWORD t;
2917 	int lab;
2918 
2919 	if (retlab != NOLAB) {
2920 		plabel(retlab);
2921 		retlab = getlab();
2922 	}
2923 
2924 	t = DECREF(cftnsp->stype);
2925 	if (t == BOOL)
2926 		t = BOOL_TYPE;
2927 
2928 	p = block(NAME, NIL, NIL, INT, 0, 0);
2929 	p->n_sp = lookup(stack_chk_canary, SNORMAL);
2930 	p = clocal(p);
2931 
2932 	q = block(REG, NIL, NIL, INCREF(INT), 0, 0);
2933 	q->n_lval = 0;
2934 	q->n_rval = FPREG;
2935 	q = cast(q, INT, 0);
2936 	q = buildtree(ER, p, q);
2937 
2938 	p = block(NAME, NIL, NIL, INT, 0, 0);
2939 	p->n_sp = lookup(stack_chk_guard, SNORMAL);
2940 	p = clocal(p);
2941 
2942 	lab = getlab();
2943 	cbranch(buildtree(EQ, p, q), bcon(lab));
2944 
2945 	p = block(NAME, NIL, NIL, FTN+VOID, 0, 0);
2946 	p->n_sp = lookup(stack_chk_fail, SNORMAL);
2947 	p = clocal(p);
2948 
2949 	q = eve(bdty(STRING, cftnsp->sname, 0));
2950 	ecomp(buildtree(CALL, p, q));
2951 
2952 	plabel(lab);
2953 }
2954 
2955 /*
2956  * Allocate on the permanent heap for inlines, otherwise temporary heap.
2957  */
2958 void *
blkalloc(int size)2959 blkalloc(int size)
2960 {
2961 	return isinlining || blevel < 2 ?  permalloc(size) : tmpalloc(size);
2962 }
2963 
2964 /*
2965  * Allocate on the permanent heap for inlines, otherwise temporary heap.
2966  */
2967 void *
inlalloc(int size)2968 inlalloc(int size)
2969 {
2970 	return isinlining ?  permalloc(size) : tmpalloc(size);
2971 }
2972 
2973 struct attr *
attr_new(int type,int nelem)2974 attr_new(int type, int nelem)
2975 {
2976 	struct attr *ap;
2977 	int sz;
2978 
2979 	sz = sizeof(struct attr) + nelem * sizeof(union aarg);
2980 
2981 	ap = memset(blkalloc(sz), 0, sz);
2982 	ap->atype = type;
2983 	return ap;
2984 }
2985 
2986 /*
2987  * Add attribute list new before old and return new.
2988  */
2989 struct attr *
attr_add(struct attr * old,struct attr * new)2990 attr_add(struct attr *old, struct attr *new)
2991 {
2992 	struct attr *ap;
2993 
2994 	if (new == NULL)
2995 		return old; /* nothing to add */
2996 
2997 	for (ap = new; ap->next; ap = ap->next)
2998 		;
2999 	ap->next = old;
3000 	return new;
3001 }
3002 
3003 /*
3004  * Search for attribute type in list ap.  Return entry or NULL.
3005  */
3006 struct attr *
attr_find(struct attr * ap,int type)3007 attr_find(struct attr *ap, int type)
3008 {
3009 
3010 	for (; ap && ap->atype != type; ap = ap->next)
3011 		;
3012 	return ap;
3013 }
3014 
3015 /*
3016  * Copy an attribute struct.
3017  * Return destination.
3018  */
3019 struct attr *
attr_copy(struct attr * aps,struct attr * apd,int n)3020 attr_copy(struct attr *aps, struct attr *apd, int n)
3021 {
3022 	int sz = sizeof(struct attr) + n * sizeof(union aarg);
3023 	return memcpy(apd, aps, sz);
3024 }
3025 
3026 /*
3027  * Duplicate an attribute, like strdup.
3028  */
3029 struct attr *
attr_dup(struct attr * ap,int n)3030 attr_dup(struct attr *ap, int n)
3031 {
3032 	int sz = sizeof(struct attr) + n * sizeof(union aarg);
3033 	ap = memcpy(blkalloc(sz), ap, sz);
3034 	ap->next = NULL;
3035 	return ap;
3036 }
3037 
3038 /*
3039  * Fetch pointer to first member in a struct list.
3040  */
3041 struct symtab *
strmemb(struct attr * ap)3042 strmemb(struct attr *ap)
3043 {
3044 
3045 	if ((ap = attr_find(ap, ATTR_STRUCT)) == NULL)
3046 		cerror("strmemb");
3047 	return ap->amlist;
3048 }
3049 
3050 #ifndef NO_COMPLEX
3051 
3052 static char *real, *imag;
3053 static struct symtab *cxsp[3], *cxmul[3], *cxdiv[3];
3054 static char *cxnmul[] = { "__mulsc3", "__muldc3", "__mulxc3" };
3055 static char *cxndiv[] = { "__divsc3", "__divdc3", "__divxc3" };
3056 /*
3057  * As complex numbers internally are handled as structs, create
3058  * these by hand-crafting them.
3059  */
3060 void
complinit(void)3061 complinit(void)
3062 {
3063 	struct attr *ap;
3064 	struct rstack *rp;
3065 	NODE *p, *q;
3066 	char *n[] = { "0f", "0d", "0l" };
3067 	int i, d_debug;
3068 
3069 	d_debug = ddebug;
3070 	ddebug = 0;
3071 	real = addname("__real");
3072 	imag = addname("__imag");
3073 	p = block(NAME, NIL, NIL, FLOAT, 0, 0);
3074 	for (i = 0; i < 3; i++) {
3075 		p->n_type = FLOAT+i;
3076 		rpole = rp = bstruct(NULL, STNAME, NULL);
3077 		soumemb(p, real, 0);
3078 		soumemb(p, imag, 0);
3079 		q = dclstruct(rp);
3080 		cxsp[i] = q->n_sp = lookup(addname(n[i]), 0);
3081 		defid(q, TYPEDEF);
3082 		ap = attr_new(ATTR_COMPLEX, 0);
3083 		q->n_sp->sap = attr_add(q->n_sp->sap, ap);
3084 		nfree(q);
3085 	}
3086 	/* create function declarations for external ops */
3087 	for (i = 0; i < 3; i++) {
3088 		cxnmul[i] = addname(cxnmul[i]);
3089 		p->n_sp = cxmul[i] = lookup(cxnmul[i], 0);
3090 		p->n_type = FTN|STRTY;
3091 		p->n_ap = cxsp[i]->sap;
3092 		p->n_df = cxsp[i]->sdf;
3093 		defid2(p, EXTERN, 0);
3094 		cxmul[i]->sdf = permalloc(sizeof(union dimfun));
3095 		cxmul[i]->sdf->dfun = NULL;
3096 		cxndiv[i] = addname(cxndiv[i]);
3097 		p->n_sp = cxdiv[i] = lookup(cxndiv[i], 0);
3098 		p->n_type = FTN|STRTY;
3099 		p->n_ap = cxsp[i]->sap;
3100 		p->n_df = cxsp[i]->sdf;
3101 		defid2(p, EXTERN, 0);
3102 		cxdiv[i]->sdf = permalloc(sizeof(union dimfun));
3103 		cxdiv[i]->sdf->dfun = NULL;
3104 	}
3105 	nfree(p);
3106 	ddebug = d_debug;
3107 }
3108 
3109 static TWORD
maxtt(NODE * p)3110 maxtt(NODE *p)
3111 {
3112 	TWORD t;
3113 
3114 	t = ANYCX(p) ? strmemb(p->n_ap)->stype : p->n_type;
3115 	t = BTYPE(t);
3116 	if (t == VOID)
3117 		t = CHAR; /* pointers */
3118 	if (ISITY(t))
3119 		t -= (FIMAG - FLOAT);
3120 	return t;
3121 }
3122 
3123 /*
3124  * Return the highest real floating point type.
3125  * Known that at least one type is complex or imaginary.
3126  */
3127 static TWORD
maxtyp(NODE * l,NODE * r)3128 maxtyp(NODE *l, NODE *r)
3129 {
3130 	TWORD tl, tr, t;
3131 
3132 	tl = maxtt(l);
3133 	tr = maxtt(r);
3134 	t = tl > tr ? tl : tr;
3135 	if (!ISFTY(t))
3136 		cerror("maxtyp");
3137 	return t;
3138 }
3139 
3140 /*
3141  * Fetch space on stack for complex struct.
3142  */
3143 static NODE *
cxstore(TWORD t)3144 cxstore(TWORD t)
3145 {
3146 	struct symtab s;
3147 
3148 	s = *cxsp[t - FLOAT];
3149 	s.sclass = AUTO;
3150 	s.soffset = NOOFFSET;
3151 	oalloc(&s, &autooff);
3152 	return nametree(&s);
3153 }
3154 
3155 #define	comop(x,y) buildtree(COMOP, x, y)
3156 
3157 /*
3158  * Convert node p to complex type dt.
3159  */
3160 static NODE *
mkcmplx(NODE * p,TWORD dt)3161 mkcmplx(NODE *p, TWORD dt)
3162 {
3163 	NODE *q, *r, *i, *t;
3164 
3165 	if (!ANYCX(p)) {
3166 		/* Not complex, convert to complex on stack */
3167 		q = cxstore(dt);
3168 		if (ISITY(p->n_type)) {
3169 			p->n_type = p->n_type - FIMAG + FLOAT;
3170 			r = bcon(0);
3171 			i = p;
3172 		} else {
3173 			if (ISPTR(p->n_type))
3174 				p = cast(p, INTPTR, 0);
3175 			r = p;
3176 			i = bcon(0);
3177 		}
3178 		p = buildtree(ASSIGN, structref(ccopy(q), DOT, real), r);
3179 		p = comop(p, buildtree(ASSIGN, structref(ccopy(q), DOT, imag), i));
3180 		p = comop(p, q);
3181 	} else {
3182 		if (strmemb(p->n_ap)->stype != dt) {
3183 			q = cxstore(dt);
3184 			p = buildtree(ADDROF, p, NIL);
3185 			t = tempnode(0, p->n_type, p->n_df, p->n_ap);
3186 			p = buildtree(ASSIGN, ccopy(t), p);
3187 			p = comop(p, buildtree(ASSIGN,
3188 			    structref(ccopy(q), DOT, real),
3189 			    structref(ccopy(t), STREF, real)));
3190 			p = comop(p, buildtree(ASSIGN,
3191 			    structref(ccopy(q), DOT, imag),
3192 			    structref(t, STREF, imag)));
3193 			p = comop(p, q);
3194 		}
3195 	}
3196 	return p;
3197 }
3198 
3199 static NODE *
cxasg(NODE * l,NODE * r)3200 cxasg(NODE *l, NODE *r)
3201 {
3202 	TWORD tl, tr;
3203 
3204 	tl = strattr(l->n_ap) ? strmemb(l->n_ap)->stype : 0;
3205 	tr = strattr(r->n_ap) ? strmemb(r->n_ap)->stype : 0;
3206 
3207 	if (ANYCX(l) && ANYCX(r) && tl != tr) {
3208 		/* different types in structs */
3209 		r = mkcmplx(r, tl);
3210 	} else if (!ANYCX(l))
3211 		r = structref(r, DOT, ISITY(l->n_type) ? imag : real);
3212 	else if (!ANYCX(r))
3213 		r = mkcmplx(r, tl);
3214 	return buildtree(ASSIGN, l, r);
3215 }
3216 
3217 /*
3218  * Fixup complex operations.
3219  * At least one operand is complex.
3220  */
3221 NODE *
cxop(int op,NODE * l,NODE * r)3222 cxop(int op, NODE *l, NODE *r)
3223 {
3224 	TWORD mxtyp;
3225 	NODE *p, *q;
3226 	NODE *ltemp, *rtemp;
3227 	NODE *real_l, *imag_l;
3228 	NODE *real_r, *imag_r;
3229 
3230 	if (op == ASSIGN)
3231 		return cxasg(l, r);
3232 
3233 	mxtyp = maxtyp(l, r);
3234 	l = mkcmplx(l, mxtyp);
3235 	if (op != UMINUS)
3236 		r = mkcmplx(r, mxtyp);
3237 
3238 	if (op == COLON)
3239 		return buildtree(COLON, l, r);
3240 
3241 	/* put a pointer to left and right elements in a TEMP */
3242 	l = buildtree(ADDROF, l, NIL);
3243 	ltemp = tempnode(0, l->n_type, l->n_df, l->n_ap);
3244 	l = buildtree(ASSIGN, ccopy(ltemp), l);
3245 
3246 	if (op != UMINUS) {
3247 		r = buildtree(ADDROF, r, NIL);
3248 		rtemp = tempnode(0, r->n_type, r->n_df, r->n_ap);
3249 		r = buildtree(ASSIGN, ccopy(rtemp), r);
3250 
3251 		p = comop(l, r);
3252 	} else
3253 		p = l;
3254 
3255 	/* create the four trees needed for calculation */
3256 	real_l = structref(ccopy(ltemp), STREF, real);
3257 	imag_l = structref(ltemp, STREF, imag);
3258 	if (op != UMINUS) {
3259 		real_r = structref(ccopy(rtemp), STREF, real);
3260 		imag_r = structref(rtemp, STREF, imag);
3261 	}
3262 
3263 	/* get storage on stack for the result */
3264 	q = cxstore(mxtyp);
3265 
3266 	switch (op) {
3267 	case NE:
3268 	case EQ:
3269 		tfree(q);
3270 		p = buildtree(op, comop(p, real_l), real_r);
3271 		q = buildtree(op, imag_l, imag_r);
3272 		p = buildtree(op == EQ ? ANDAND : OROR, p, q);
3273 		return p;
3274 
3275 	case ANDAND:
3276 	case OROR: /* go via EQ to get INT of it */
3277 		tfree(q);
3278 		p = buildtree(NE, comop(p, real_l), bcon(0)); /* gets INT */
3279 		q = buildtree(NE, imag_l, bcon(0));
3280 		p = buildtree(OR, p, q);
3281 
3282 		q = buildtree(NE, real_r, bcon(0));
3283 		q = buildtree(OR, q, buildtree(NE, imag_r, bcon(0)));
3284 
3285 		p = buildtree(op, p, q);
3286 		return p;
3287 
3288 	case UMINUS:
3289 		p = comop(p, buildtree(ASSIGN, structref(ccopy(q), DOT, real),
3290 		    buildtree(op, real_l, NIL)));
3291 		p = comop(p, buildtree(ASSIGN, structref(ccopy(q), DOT, imag),
3292 		    buildtree(op, imag_l, NIL)));
3293 		break;
3294 
3295 	case PLUS:
3296 	case MINUS:
3297 		p = comop(p, buildtree(ASSIGN, structref(ccopy(q), DOT, real),
3298 		    buildtree(op, real_l, real_r)));
3299 		p = comop(p, buildtree(ASSIGN, structref(ccopy(q), DOT, imag),
3300 		    buildtree(op, imag_l, imag_r)));
3301 		break;
3302 
3303 	case MUL:
3304 	case DIV:
3305 		/* Complex mul is "complex" */
3306 		/* (u+iv)*(x+iy)=((u*x)-(v*y))+i(v*x+y*u) */
3307 		/* Complex div is even more "complex" */
3308 		/* (u+iv)/(x+iy)=(u*x+v*y)/(x*x+y*y)+i((v*x-u*y)/(x*x+y*y)) */
3309 		/* but we need to do it via a subroutine */
3310 		tfree(q);
3311 		p = buildtree(CM, comop(p, real_l), imag_l);
3312 		p = buildtree(CM, p, real_r);
3313 		p = buildtree(CM, p, imag_r);
3314 		q = nametree(op == DIV ?
3315 		    cxdiv[mxtyp-FLOAT] : cxmul[mxtyp-FLOAT]);
3316 		return buildtree(CALL, q, p);
3317 		break;
3318 	default:
3319 		uerror("illegal operator %s", copst(op));
3320 	}
3321 	return comop(p, q);
3322 }
3323 
3324 /*
3325  * Fixup imaginary operations.
3326  * At least one operand is imaginary, none is complex.
3327  */
3328 NODE *
imop(int op,NODE * l,NODE * r)3329 imop(int op, NODE *l, NODE *r)
3330 {
3331 	NODE *p, *q;
3332 	TWORD mxtyp;
3333 	int li, ri;
3334 
3335 	li = ri = 0;
3336 	if (ISITY(l->n_type))
3337 		li = 1, l->n_type = l->n_type - (FIMAG-FLOAT);
3338 	if (ISITY(r->n_type))
3339 		ri = 1, r->n_type = r->n_type - (FIMAG-FLOAT);
3340 
3341 	mxtyp = maxtyp(l, r);
3342 	switch (op) {
3343 	case ASSIGN:
3344 		/* if both are imag, store value, otherwise store 0.0 */
3345 		if (!(li && ri)) {
3346 			tfree(r);
3347 			r = bcon(0);
3348 		}
3349 		p = buildtree(ASSIGN, l, r);
3350 		p->n_type += (FIMAG-FLOAT);
3351 		break;
3352 
3353 	case PLUS:
3354 		if (li && ri) {
3355 			p = buildtree(PLUS, l, r);
3356 			p->n_type += (FIMAG-FLOAT);
3357 		} else {
3358 			/* If one is imaginary and one is real, make complex */
3359 			if (li)
3360 				q = l, l = r, r = q; /* switch */
3361 			q = cxstore(mxtyp);
3362 			p = buildtree(ASSIGN,
3363 			    structref(ccopy(q), DOT, real), l);
3364 			p = comop(p, buildtree(ASSIGN,
3365 			    structref(ccopy(q), DOT, imag), r));
3366 			p = comop(p, q);
3367 		}
3368 		break;
3369 
3370 	case MINUS:
3371 		if (li && ri) {
3372 			p = buildtree(MINUS, l, r);
3373 			p->n_type += (FIMAG-FLOAT);
3374 		} else if (li) {
3375 			q = cxstore(mxtyp);
3376 			p = buildtree(ASSIGN, structref(ccopy(q), DOT, real),
3377 			    buildtree(UMINUS, r, NIL));
3378 			p = comop(p, buildtree(ASSIGN,
3379 			    structref(ccopy(q), DOT, imag), l));
3380 			p = comop(p, q);
3381 		} else /* if (ri) */ {
3382 			q = cxstore(mxtyp);
3383 			p = buildtree(ASSIGN,
3384 			    structref(ccopy(q), DOT, real), l);
3385 			p = comop(p, buildtree(ASSIGN,
3386 			    structref(ccopy(q), DOT, imag),
3387 			    buildtree(UMINUS, r, NIL)));
3388 			p = comop(p, q);
3389 		}
3390 		break;
3391 
3392 	case MUL:
3393 		p = buildtree(MUL, l, r);
3394 		if (li && ri)
3395 			p = buildtree(UMINUS, p, NIL);
3396 		if (li ^ ri)
3397 			p->n_type += (FIMAG-FLOAT);
3398 		break;
3399 
3400 	case DIV:
3401 		p = buildtree(DIV, l, r);
3402 		if (ri && !li)
3403 			p = buildtree(UMINUS, p, NIL);
3404 		if (li ^ ri)
3405 			p->n_type += (FIMAG-FLOAT);
3406 		break;
3407 
3408 	case EQ:
3409 	case NE:
3410 	case LT:
3411 	case LE:
3412 	case GT:
3413 	case GE:
3414 		if (li ^ ri) { /* always 0 */
3415 			tfree(l);
3416 			tfree(r);
3417 			p = bcon(0);
3418 		} else
3419 			p = buildtree(op, l, r);
3420 		break;
3421 
3422 	default:
3423 		cerror("imop");
3424 		p = NULL;
3425 	}
3426 	return p;
3427 }
3428 
3429 NODE *
cxelem(int op,NODE * p)3430 cxelem(int op, NODE *p)
3431 {
3432 
3433 	if (ANYCX(p)) {
3434 		p = structref(p, DOT, op == XREAL ? real : imag);
3435 	} else if (op == XIMAG) {
3436 		/* XXX  sanitycheck? */
3437 		tfree(p);
3438 		p = bcon(0);
3439 	}
3440 	return p;
3441 }
3442 
3443 NODE *
cxconj(NODE * p)3444 cxconj(NODE *p)
3445 {
3446 	NODE *q, *r;
3447 
3448 	/* XXX side effects? */
3449 	q = cxstore(strmemb(p->n_ap)->stype);
3450 	r = buildtree(ASSIGN, structref(ccopy(q), DOT, real),
3451 	    structref(ccopy(p), DOT, real));
3452 	r = comop(r, buildtree(ASSIGN, structref(ccopy(q), DOT, imag),
3453 	    buildtree(UMINUS, structref(p, DOT, imag), NIL)));
3454 	return comop(r, q);
3455 }
3456 
3457 /*
3458  * Prepare for return.
3459  * There may be implicit casts to other types.
3460  */
3461 NODE *
cxret(NODE * p,NODE * q)3462 cxret(NODE *p, NODE *q)
3463 {
3464 	if (ANYCX(q)) { /* Return complex type */
3465 		p = mkcmplx(p, strmemb(q->n_ap)->stype);
3466 	} else if (q->n_type < STRTY || ISITY(q->n_type)) { /* real or imag */
3467 		p = structref(p, DOT, ISITY(q->n_type) ? imag : real);
3468 		if (p->n_type != q->n_type)
3469 			p = cast(p, q->n_type, 0);
3470 	} else
3471 		cerror("cxred failing type");
3472 	return p;
3473 }
3474 
3475 /*
3476  * either p1 or p2 is complex, so fixup the remaining type accordingly.
3477  */
3478 NODE *
cxcast(NODE * p1,NODE * p2)3479 cxcast(NODE *p1, NODE *p2)
3480 {
3481 	if (ANYCX(p1) && ANYCX(p2)) {
3482 		if (p1->n_type != p2->n_type)
3483 			p2 = mkcmplx(p2, p1->n_type);
3484 	} else if (ANYCX(p1)) {
3485 		p2 = mkcmplx(p2, strmemb(p1->n_ap)->stype);
3486 	} else /* if (ANYCX(p2)) */ {
3487 		p2 = cast(structref(p2, DOT, real), p1->n_type, 0);
3488 	}
3489 	nfree(p1);
3490 	return p2;
3491 }
3492 
3493 static void
cxargfixup(NODE * a,TWORD dt,struct attr * ap)3494 cxargfixup(NODE *a, TWORD dt, struct attr *ap)
3495 {
3496 	NODE *p;
3497 	TWORD t;
3498 
3499 	p = talloc();
3500 	*p = *a;
3501 	if (dt == STRTY) {
3502 		/* dest complex */
3503 		t = strmemb(ap)->stype;
3504 		p = mkcmplx(p, t);
3505 	} else {
3506 		/* src complex, not dest */
3507 		p = structref(p, DOT, ISFTY(dt) ? real : imag);
3508 	}
3509 	*a = *p;
3510 	nfree(p);
3511 }
3512 #endif
3513