Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

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