decl.c revision 80284
1/*	$NetBSD: decl.c,v 1.11 1995/10/02 17:34:16 jpo Exp $	*/
2
3/*
4 * Copyright (c) 1994, 1995 Jochen Pohl
5 * All Rights Reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 *    must display the following acknowledgement:
17 *      This product includes software developed by Jochen Pohl for
18 *	The NetBSD Project.
19 * 4. The name of the author may not be used to endorse or promote products
20 *    derived from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34#ifndef lint
35static const char rcsid[] =
36  "$FreeBSD: head/usr.bin/xlint/lint1/decl.c 80284 2001-07-24 14:02:07Z obrien $";
37#endif
38
39#include <sys/param.h>
40#include <limits.h>
41#include <stdlib.h>
42#include <string.h>
43
44#include "lint1.h"
45
46const	char *unnamed = "<unnamed>";
47
48/* contains various information and classification on types */
49ttab_t	ttab[NTSPEC];
50
51/* shared type structures for arithmtic types and void */
52static	type_t	*typetab;
53
54/* value of next enumerator during declaration of enum types */
55int	enumval;
56
57/*
58 * pointer to top element of a stack which contains informations local
59 * to nested declarations
60 */
61dinfo_t	*dcs;
62
63static	type_t	*tdeferr __P((type_t *, tspec_t));
64static	void	settdsym __P((type_t *, sym_t *));
65static	tspec_t	mrgtspec __P((tspec_t, tspec_t));
66static	void	align __P((int, int));
67static	sym_t	*newtag __P((sym_t *, scl_t, int, int));
68static	int	eqargs __P((type_t *, type_t *, int *));
69static	int	mnoarg __P((type_t *, int *));
70static	int	chkosdef __P((sym_t *, sym_t *));
71static	int	chkptdecl __P((sym_t *, sym_t *));
72static	sym_t	*nsfunc __P((sym_t *, sym_t *));
73static	void	osfunc __P((sym_t *, sym_t *));
74static	void	ledecl __P((sym_t *));
75static	int	chkinit __P((sym_t *));
76static	void	chkausg __P((int, sym_t *));
77static	void	chkvusg __P((int, sym_t *));
78static	void	chklusg __P((sym_t *));
79static	void	chktusg __P((sym_t *));
80static	void	chkglvar __P((sym_t *));
81static	void	glchksz __P((sym_t *));
82
83/*
84 * initializes all global vars used in declarations
85 */
86void
87initdecl()
88{
89	int	i;
90	static	struct {
91		tspec_t	it_tspec;
92		ttab_t	it_ttab;
93	} ittab[] = {
94		{ SIGNED,   { 0, 0,
95			      SIGNED, UNSIGN,
96			      0, 0, 0, 0, 0, "signed" } },
97		{ UNSIGN,   { 0, 0,
98			      SIGNED, UNSIGN,
99			      0, 0, 0, 0, 0, "unsigned" } },
100		{ CHAR,	    { CHAR_BIT, CHAR_BIT,
101			      SCHAR, UCHAR,
102			      1, 0, 0, 1, 1, "char" } },
103		{ SCHAR,    { CHAR_BIT, CHAR_BIT,
104			      SCHAR, UCHAR,
105			      1, 0, 0, 1, 1, "signed char" } },
106		{ UCHAR,    { CHAR_BIT, CHAR_BIT,
107			      SCHAR, UCHAR,
108			      1, 1, 0, 1, 1, "unsigned char" } },
109		{ SHORT,    { sizeof (short) * CHAR_BIT, 2 * CHAR_BIT,
110			      SHORT, USHORT,
111			      1, 0, 0, 1, 1, "short" } },
112		{ USHORT,   { sizeof (u_short) * CHAR_BIT, 2 * CHAR_BIT,
113			      SHORT, USHORT,
114			      1, 1, 0, 1, 1, "unsigned short" } },
115		{ INT,      { sizeof (int) * CHAR_BIT, 3 * CHAR_BIT,
116			      INT, UINT,
117			      1, 0, 0, 1, 1, "int" } },
118		{ UINT,     { sizeof (u_int) * CHAR_BIT, 3 * CHAR_BIT,
119			      INT, UINT,
120			      1, 1, 0, 1, 1, "unsigned int" } },
121		{ LONG,     { sizeof (long) * CHAR_BIT, 4 * CHAR_BIT,
122			      LONG, ULONG,
123			      1, 0, 0, 1, 1, "long" } },
124		{ ULONG,    { sizeof (u_long) * CHAR_BIT, 4 * CHAR_BIT,
125			      LONG, ULONG,
126			      1, 1, 0, 1, 1, "unsigned long" } },
127		{ QUAD,     { sizeof (quad_t) * CHAR_BIT, 8 * CHAR_BIT,
128			      QUAD, UQUAD,
129			      1, 0, 0, 1, 1, "long long" } },
130		{ UQUAD,    { sizeof (u_quad_t) * CHAR_BIT, 8 * CHAR_BIT,
131			      QUAD, UQUAD,
132			      1, 1, 0, 1, 1, "unsigned long long" } },
133		{ FLOAT,    { sizeof (float) * CHAR_BIT, 4 * CHAR_BIT,
134			      FLOAT, FLOAT,
135			      0, 0, 1, 1, 1, "float" } },
136		{ DOUBLE,   { sizeof (double) * CHAR_BIT, 8 * CHAR_BIT,
137			      DOUBLE, DOUBLE,
138			      0, 0, 1, 1, 1, "double" } },
139		{ LDOUBLE,  { sizeof (ldbl_t) * CHAR_BIT, 10 * CHAR_BIT,
140			      LDOUBLE, LDOUBLE,
141			      0, 0, 1, 1, 1, "long double" } },
142		{ VOID,     { -1, -1,
143			      VOID, VOID,
144			      0, 0, 0, 0, 0, "void" } },
145		{ STRUCT,   { -1, -1,
146			      STRUCT, STRUCT,
147			      0, 0, 0, 0, 0, "struct" } },
148		{ UNION,    { -1, -1,
149			      UNION, UNION,
150			      0, 0, 0, 0, 0, "union" } },
151		{ ENUM,     { sizeof (int) * CHAR_BIT, 3 * CHAR_BIT,
152			      ENUM, ENUM,
153			      1, 0, 0, 1, 1, "enum" } },
154		{ PTR,      { sizeof (void *) * CHAR_BIT, 4 * CHAR_BIT,
155			      PTR, PTR,
156			      0, 1, 0, 0, 1, "pointer" } },
157		{ ARRAY,    { -1, -1,
158			      ARRAY, ARRAY,
159			      0, 0, 0, 0, 0, "array" } },
160		{ FUNC,     { -1, -1,
161			      FUNC, FUNC,
162			      0, 0, 0, 0, 0, "function" } },
163	};
164
165	/* declaration stack */
166	if ((dcs = calloc(1, sizeof (dinfo_t))) == NULL)
167		nomem();
168	dcs->d_ctx = EXTERN;
169	dcs->d_ldlsym = &dcs->d_dlsyms;
170
171	/* type information and classification */
172	for (i = 0; i < sizeof (ittab) / sizeof (ittab[0]); i++)
173		STRUCT_ASSIGN(ttab[ittab[i].it_tspec], ittab[i].it_ttab);
174	if (!pflag) {
175		for (i = 0; i < NTSPEC; i++)
176			ttab[i].tt_psz = ttab[i].tt_sz;
177	}
178
179	/* shared type structures */
180	if ((typetab = calloc(NTSPEC, sizeof (type_t))) == NULL)
181		nomem();
182	for (i = 0; i < NTSPEC; i++)
183		typetab[i].t_tspec = NOTSPEC;
184	typetab[CHAR].t_tspec = CHAR;
185	typetab[SCHAR].t_tspec = SCHAR;
186	typetab[UCHAR].t_tspec = UCHAR;
187	typetab[SHORT].t_tspec = SHORT;
188	typetab[USHORT].t_tspec = USHORT;
189	typetab[INT].t_tspec = INT;
190	typetab[UINT].t_tspec = UINT;
191	typetab[LONG].t_tspec = LONG;
192	typetab[ULONG].t_tspec = ULONG;
193	typetab[QUAD].t_tspec = QUAD;
194	typetab[UQUAD].t_tspec = UQUAD;
195	typetab[FLOAT].t_tspec = FLOAT;
196	typetab[DOUBLE].t_tspec = DOUBLE;
197	typetab[LDOUBLE].t_tspec = LDOUBLE;
198	typetab[VOID].t_tspec = VOID;
199	/*
200	 * Next two are not real types. They are only used by the parser
201	 * to return keywords "signed" and "unsigned"
202	 */
203	typetab[SIGNED].t_tspec = SIGNED;
204	typetab[UNSIGN].t_tspec = UNSIGN;
205}
206
207/*
208 * Returns a shared type structure vor arithmetic types and void.
209 *
210 * It's important do duplicate this structure (using duptyp() or tdupdyp())
211 * if it is to be modified (adding qualifiers or anything else).
212 */
213type_t *
214gettyp(t)
215	tspec_t	t;
216{
217	return (&typetab[t]);
218}
219
220type_t *
221duptyp(tp)
222	const	type_t *tp;
223{
224	type_t	*ntp;
225
226	ntp = getblk(sizeof (type_t));
227	STRUCT_ASSIGN(*ntp, *tp);
228	return (ntp);
229}
230
231/*
232 * Use tduptyp() instead of duptyp() inside expressions (if the
233 * allocated memory should be freed after the expr).
234 */
235type_t *
236tduptyp(tp)
237	const	type_t *tp;
238{
239	type_t	*ntp;
240
241	ntp = tgetblk(sizeof (type_t));
242	STRUCT_ASSIGN(*ntp, *tp);
243	return (ntp);
244}
245
246/*
247 * Returns 1 if the argument is void or an incomplete array,
248 * struct, union or enum type.
249 */
250int
251incompl(tp)
252	type_t	*tp;
253{
254	tspec_t	t;
255
256	if ((t = tp->t_tspec) == VOID) {
257		return (1);
258	} else if (t == ARRAY) {
259		return (tp->t_aincompl);
260	} else if (t == STRUCT || t == UNION) {
261		return (tp->t_str->sincompl);
262	} else if (t == ENUM) {
263		return (tp->t_enum->eincompl);
264	}
265	return (0);
266}
267
268/*
269 * Set the flag for (in)complete array, struct, union or enum
270 * types.
271 */
272void
273setcompl(tp, ic)
274	type_t	*tp;
275	int	ic;
276{
277	tspec_t	t;
278
279	if ((t = tp->t_tspec) == ARRAY) {
280		tp->t_aincompl = ic;
281	} else if (t == STRUCT || t == UNION) {
282		tp->t_str->sincompl = ic;
283	} else {
284		if (t != ENUM)
285			lerror("setcompl() 1");
286		tp->t_enum->eincompl = ic;
287	}
288}
289
290/*
291 * Remember the storage class of the current declaration in dcs->d_scl
292 * (the top element of the declaration stack) and detect multiple
293 * storage classes.
294 */
295void
296addscl(sc)
297	scl_t	sc;
298{
299	if (sc == INLINE) {
300		if (dcs->d_inline)
301			/* duplicate '%s' */
302			warning(10, "inline");
303		dcs->d_inline = 1;
304		return;
305	}
306	if (dcs->d_type != NULL || dcs->d_atyp != NOTSPEC ||
307	    dcs->d_smod != NOTSPEC || dcs->d_lmod != NOTSPEC) {
308		/* storage class after type is obsolescent */
309		warning(83);
310	}
311	if (dcs->d_scl == NOSCL) {
312		dcs->d_scl = sc;
313	} else {
314		/*
315		 * multiple storage classes. An error will be reported in
316		 * deftyp().
317		 */
318		dcs->d_mscl = 1;
319	}
320}
321
322/*
323 * Remember the type, modifier or typedef name returned by the parser
324 * in *dcs (top element of decl stack). This information is used in
325 * deftyp() to build the type used for all declarators in this
326 * declaration.
327 *
328 * Is tp->t_typedef 1, the type comes from a previously defined typename.
329 * Otherwise it comes from a type specifier (int, long, ...) or a
330 * struct/union/enum tag.
331 */
332void
333addtype(tp)
334	type_t	*tp;
335{
336	tspec_t	t;
337
338	if (tp->t_typedef) {
339		if (dcs->d_type != NULL || dcs->d_atyp != NOTSPEC ||
340		    dcs->d_lmod != NOTSPEC || dcs->d_smod != NOTSPEC) {
341			/*
342			 * something like "typedef int a; int a b;"
343			 * This should not happen with current grammar.
344			 */
345			lerror("addtype()");
346		}
347		dcs->d_type = tp;
348		return;
349	}
350
351	t = tp->t_tspec;
352
353	if (t == STRUCT || t == UNION || t == ENUM) {
354		/*
355		 * something like "int struct a ..."
356		 * struct/union/enum with anything else is not allowed
357		 */
358		if (dcs->d_type != NULL || dcs->d_atyp != NOTSPEC ||
359		    dcs->d_lmod != NOTSPEC || dcs->d_smod != NOTSPEC) {
360			/*
361			 * remember that an error must be reported in
362			 * deftyp().
363			 */
364			dcs->d_terr = 1;
365			dcs->d_atyp = dcs->d_lmod = dcs->d_smod = NOTSPEC;
366		}
367		dcs->d_type = tp;
368		return;
369	}
370
371	if (dcs->d_type != NULL && !dcs->d_type->t_typedef) {
372		/*
373		 * something like "struct a int"
374		 * struct/union/enum with anything else is not allowed
375		 */
376		dcs->d_terr = 1;
377		return;
378	}
379
380	if (t == LONG && dcs->d_lmod == LONG) {
381		/* "long long" or "long ... long" */
382		t = QUAD;
383		dcs->d_lmod = NOTSPEC;
384		if (!quadflg)
385			/* %s C does not support 'long long' */
386			(void)gnuism(265, tflag ? "traditional" : "ANSI");
387	}
388
389	if (dcs->d_type != NULL && dcs->d_type->t_typedef) {
390		/* something like "typedef int a; a long ..." */
391		dcs->d_type = tdeferr(dcs->d_type, t);
392		return;
393	}
394
395	/* now it can be only a combination of arithmetic types and void */
396	if (t == SIGNED || t == UNSIGN) {
397		/* remeber specifiers "signed" and "unsigned" in dcs->d_smod */
398		if (dcs->d_smod != NOTSPEC)
399			/*
400			 * more then one "signed" and/or "unsigned"; print
401			 * an error in deftyp()
402			 */
403			dcs->d_terr = 1;
404		dcs->d_smod = t;
405	} else if (t == SHORT || t == LONG || t == QUAD) {
406		/*
407		 * remember specifiers "short", "long" and "long long" in
408		 * dcs->d_lmod
409		 */
410		if (dcs->d_lmod != NOTSPEC)
411			/* more than one, print error in deftyp() */
412			dcs->d_terr = 1;
413		dcs->d_lmod = t;
414	} else {
415		/*
416		 * remember specifiers "void", "char", "int", "float" or
417		 * "double" int dcs->d_atyp
418		 */
419		if (dcs->d_atyp != NOTSPEC)
420			/* more than one, print error in deftyp() */
421			dcs->d_terr = 1;
422		dcs->d_atyp = t;
423	}
424}
425
426/*
427 * called if a list of declaration specifiers contains a typedef name
428 * and other specifiers (except struct, union, enum, typedef name)
429 */
430static type_t *
431tdeferr(td, t)
432	type_t	*td;
433	tspec_t	t;
434{
435	tspec_t	t2;
436
437	t2 = td->t_tspec;
438
439	switch (t) {
440	case SIGNED:
441	case UNSIGN:
442		if (t2 == CHAR || t2 == SHORT || t2 == INT || t2 == LONG ||
443		    t2 == QUAD) {
444			if (!tflag)
445				/* modifying typedef with ... */
446				warning(5, ttab[t].tt_name);
447			td = duptyp(gettyp(mrgtspec(t2, t)));
448			td->t_typedef = 1;
449			return (td);
450		}
451		break;
452	case SHORT:
453		if (t2 == INT || t2 == UINT) {
454			/* modifying typedef with ... */
455			warning(5, "short");
456			td = duptyp(gettyp(t2 == INT ? SHORT : USHORT));
457			td->t_typedef = 1;
458			return (td);
459		}
460		break;
461	case LONG:
462		if (t2 == INT || t2 == UINT || t2 == LONG || t2 == ULONG ||
463		    t2 == FLOAT || t2 == DOUBLE) {
464			/* modifying typedef with ... */
465			warning(5, "long");
466			if (t2 == INT) {
467				td = gettyp(LONG);
468			} else if (t2 == UINT) {
469				td = gettyp(ULONG);
470			} else if (t2 == LONG) {
471				td = gettyp(QUAD);
472			} else if (t2 == ULONG) {
473				td = gettyp(UQUAD);
474			} else if (t2 == FLOAT) {
475				td = gettyp(DOUBLE);
476			} else if (t2 == DOUBLE) {
477				td = gettyp(LDOUBLE);
478			}
479			td = duptyp(td);
480			td->t_typedef = 1;
481			return (td);
482		}
483		break;
484		/* LINTED (enumeration values not handled in switch) */
485	default:
486	}
487
488	/* Anything other is not accepted. */
489
490	dcs->d_terr = 1;
491	return (td);
492}
493
494/*
495 * Remember the symbol of a typedef name (2nd arg) in a struct, union
496 * or enum tag if the typedef name is the first defined for this tag.
497 *
498 * If the tag is unnamed, the typdef name is used for identification
499 * of this tag in lint2. Although its possible that more then one typedef
500 * name is defined for one tag, the first name defined should be unique
501 * if the tag is unnamed.
502 */
503static void
504settdsym(tp, sym)
505	type_t	*tp;
506	sym_t	*sym;
507{
508	tspec_t	t;
509
510	if ((t = tp->t_tspec) == STRUCT || t == UNION) {
511		if (tp->t_str->stdef == NULL)
512			tp->t_str->stdef = sym;
513	} else if (t == ENUM) {
514		if (tp->t_enum->etdef == NULL)
515			tp->t_enum->etdef = sym;
516	}
517}
518
519/*
520 * Remember a qualifier which is part of the declaration specifiers
521 * (and not the declarator) in the top element of the declaration stack.
522 * Also detect multiple qualifiers of the same kind.
523
524 * The rememberd qualifier is used by deftyp() to construct the type
525 * for all declarators.
526 */
527void
528addqual(q)
529	tqual_t	q;
530{
531	if (q == CONST) {
532		if (dcs->d_const) {
533			/* duplicate "%s" */
534			warning(10, "const");
535		}
536		dcs->d_const = 1;
537	} else {
538		if (q != VOLATILE)
539			lerror("addqual() 1");
540		if (dcs->d_volatile) {
541			/* duplicate "%s" */
542			warning(10, "volatile");
543		}
544		dcs->d_volatile = 1;
545	}
546}
547
548/*
549 * Go to the next declaration level (structs, nested structs, blocks,
550 * argument declaration lists ...)
551 */
552void
553pushdecl(sc)
554	scl_t	sc;
555{
556	dinfo_t	*di;
557
558	if (dflag)
559		(void)printf("pushdecl(%d)\n", (int)sc);
560
561	/* put a new element on the declaration stack */
562	if ((di = calloc(1, sizeof (dinfo_t))) == NULL)
563		nomem();
564	di->d_nxt = dcs;
565	dcs = di;
566	di->d_ctx = sc;
567	di->d_ldlsym = &di->d_dlsyms;
568}
569
570/*
571 * Go back to previous declaration level
572 */
573void
574popdecl()
575{
576	dinfo_t	*di;
577
578	if (dflag)
579		(void)printf("popdecl(%d)\n", (int)dcs->d_ctx);
580
581	if (dcs->d_nxt == NULL)
582		lerror("popdecl() 1");
583	di = dcs;
584	dcs = di->d_nxt;
585	switch (di->d_ctx) {
586	case EXTERN:
587		/* there is nothing after external declarations */
588		lerror("popdecl() 2");
589		/* NOTREACHED */
590	case MOS:
591	case MOU:
592	case ENUMCON:
593		/*
594		 * Symbols declared in (nested) structs or enums are
595		 * part of the next level (they are removed from the
596		 * symbol table if the symbols of the outher level are
597		 * removed)
598		 */
599		if ((*dcs->d_ldlsym = di->d_dlsyms) != NULL)
600			dcs->d_ldlsym = di->d_ldlsym;
601		break;
602	case ARG:
603		/*
604		 * All symbols in dcs->d_dlsyms are introduced in old style
605		 * argument declarations (it's not clean, but possible).
606		 * They are appended to the list of symbols declared in
607		 * an old style argument identifier list or a new style
608		 * parameter type list.
609		 */
610		if (di->d_dlsyms != NULL) {
611			*di->d_ldlsym = dcs->d_fpsyms;
612			dcs->d_fpsyms = di->d_dlsyms;
613		}
614		break;
615	case ABSTRACT:
616		/*
617		 * casts and sizeof
618		 * Append all symbols declared in the abstract declaration
619		 * to the list of symbols declared in the surounding decl.
620		 * or block.
621		 * XXX I'm not sure whether they should be removed from the
622		 * symbol table now or later.
623		 */
624		if ((*dcs->d_ldlsym = di->d_dlsyms) != NULL)
625			dcs->d_ldlsym = di->d_ldlsym;
626		break;
627	case AUTO:
628		/* check usage of local vars */
629		chkusage(di);
630		/* FALLTHROUGH */
631	case PARG:
632		/* usage of arguments will be checked by funcend() */
633		rmsyms(di->d_dlsyms);
634		break;
635	default:
636		lerror("popdecl() 3");
637	}
638	free(di);
639}
640
641/*
642 * Set flag d_asm in all declaration stack elements up to the
643 * outermost one.
644 *
645 * This is used to mark compound statements which have, possibly in
646 * nested compound statements, asm statements. For these compound
647 * statements no warnings about unused or unitialized variables are
648 * printed.
649 *
650 * There is no need to clear d_asm in dinfo structs with context AUTO,
651 * because these structs are freed at the end of the compound statement.
652 * But it must be cleard in the outermost dinfo struct, which has
653 * context EXTERN. This could be done in clrtyp() and would work for
654 * C, but not for C++ (due to mixed statements and declarations). Thus
655 * we clear it in glclup(), which is used to do some cleanup after
656 * global declarations/definitions.
657 */
658void
659setasm()
660{
661	dinfo_t	*di;
662
663	for (di = dcs; di != NULL; di = di->d_nxt)
664		di->d_asm = 1;
665}
666
667/*
668 * Clean all elements of the top element of declaration stack which
669 * will be used by the next declaration
670 */
671void
672clrtyp()
673{
674	dcs->d_atyp = dcs->d_smod = dcs->d_lmod = NOTSPEC;
675	dcs->d_scl = NOSCL;
676	dcs->d_type = NULL;
677	dcs->d_const = dcs->d_volatile = 0;
678	dcs->d_inline = 0;
679	dcs->d_mscl = dcs->d_terr = 0;
680	dcs->d_nedecl = 0;
681	dcs->d_notyp = 0;
682}
683
684/*
685 * Create a type structure from the informations gathered in
686 * the declaration stack.
687 * Complain about storage classes which are not possible in current
688 * context.
689 */
690void
691deftyp()
692{
693	tspec_t	t, s, l;
694	type_t	*tp;
695	scl_t	scl;
696
697	t = dcs->d_atyp;		/* CHAR, INT, FLOAT, DOUBLE, VOID */
698	s = dcs->d_smod;		/* SIGNED, UNSIGNED */
699	l = dcs->d_lmod;		/* SHORT, LONG, QUAD */
700	tp = dcs->d_type;
701	scl = dcs->d_scl;
702
703	if (t == NOTSPEC && s == NOTSPEC && l == NOTSPEC && tp == NULL)
704		dcs->d_notyp = 1;
705
706	if (tp != NULL && (t != NOTSPEC || s != NOTSPEC || l != NOTSPEC)) {
707		/* should never happen */
708		lerror("deftyp() 1");
709	}
710
711	if (tp == NULL) {
712		switch (t) {
713		case NOTSPEC:
714			t = INT;
715			/* FALLTHROUGH */
716		case INT:
717			if (s == NOTSPEC)
718				s = SIGNED;
719			break;
720		case CHAR:
721			if (l != NOTSPEC) {
722				dcs->d_terr = 1;
723				l = NOTSPEC;
724			}
725			break;
726		case FLOAT:
727			if (l == LONG) {
728				l = NOTSPEC;
729				t = DOUBLE;
730				if (!tflag)
731					/* use 'double' instead of ...  */
732					warning(6);
733			}
734			break;
735		case DOUBLE:
736			if (l == LONG) {
737				l = NOTSPEC;
738				t = LDOUBLE;
739				if (tflag)
740					/* 'long double' is illegal in ... */
741					warning(266);
742			}
743			break;
744		case VOID:
745			break;
746		default:
747			lerror("deftyp() 2");
748		}
749		if (t != INT && t != CHAR && (s != NOTSPEC || l != NOTSPEC)) {
750			dcs->d_terr = 1;
751			l = s = NOTSPEC;
752		}
753		if (l != NOTSPEC)
754			t = l;
755		dcs->d_type = gettyp(mrgtspec(t, s));
756	}
757
758	if (dcs->d_mscl) {
759		/* only one storage class allowed */
760		error(7);
761	}
762	if (dcs->d_terr) {
763		/* illegal type combination */
764		error(4);
765	}
766
767	if (dcs->d_ctx == EXTERN) {
768		if (scl == REG || scl == AUTO) {
769			/* illegal storage class */
770			error(8);
771			scl = NOSCL;
772		}
773	} else if (dcs->d_ctx == ARG || dcs->d_ctx == PARG) {
774		if (scl != NOSCL && scl != REG) {
775			/* only "register" valid ... */
776			error(9);
777			scl = NOSCL;
778		}
779	}
780
781	dcs->d_scl = scl;
782
783	if (dcs->d_const && dcs->d_type->t_const) {
784		if (!dcs->d_type->t_typedef)
785			lerror("deftyp() 3");
786		/* typedef already qualified with "%s" */
787		warning(68, "const");
788	}
789	if (dcs->d_volatile && dcs->d_type->t_volatile) {
790		if (!dcs->d_type->t_typedef)
791			lerror("deftyp() 4");
792		/* typedef already qualified with "%s" */
793		warning(68, "volatile");
794	}
795
796	if (dcs->d_const || dcs->d_volatile) {
797		dcs->d_type = duptyp(dcs->d_type);
798		dcs->d_type->t_const |= dcs->d_const;
799		dcs->d_type->t_volatile |= dcs->d_volatile;
800	}
801}
802
803/*
804 * Merge type specifiers (char, ..., long long, signed, unsigned).
805 */
806static tspec_t
807mrgtspec(t, s)
808	tspec_t	t, s;
809{
810	if (s == SIGNED || s == UNSIGN) {
811		if (t == CHAR) {
812			t = s == SIGNED ? SCHAR : UCHAR;
813		} else if (t == SHORT) {
814			t = s == SIGNED ? SHORT : USHORT;
815		} else if (t == INT) {
816			t = s == SIGNED ? INT : UINT;
817		} else if (t == LONG) {
818			t = s == SIGNED ? LONG : ULONG;
819		} else if (t == QUAD) {
820			t = s == SIGNED ? QUAD : UQUAD;
821		}
822	}
823
824	return (t);
825}
826
827/*
828 * Return the length of a type in bit.
829 *
830 * Printing a message if the outhermost dimension of an array is 0 must
831 * be done by the caller. All other problems are reported by length()
832 * if name is not NULL.
833 */
834int
835length(tp, name)
836	type_t	*tp;
837	const	char *name;
838{
839	int	elem, elsz;
840
841	elem = 1;
842	while (tp->t_tspec == ARRAY) {
843		elem *= tp->t_dim;
844		tp = tp->t_subt;
845	}
846	switch (tp->t_tspec) {
847	case FUNC:
848		/* compiler takes size of function */
849		lerror("%s", msgs[12]);
850		/* NOTREACHED */
851	case STRUCT:
852	case UNION:
853		if (incompl(tp) && name != NULL) {
854			/* incomplete structure or union %s: %s */
855			error(31, tp->t_str->stag->s_name, name);
856		}
857		elsz = tp->t_str->size;
858		break;
859	case ENUM:
860		if (incompl(tp) && name != NULL) {
861			/* incomplete enum type: %s */
862			warning(13, name);
863		}
864		/* FALLTHROUGH */
865	default:
866		elsz = size(tp->t_tspec);
867		if (elsz <= 0)
868			lerror("length()");
869		break;
870	}
871	return (elem * elsz);
872}
873
874/*
875 * Get the alignment of the given Type in bits.
876 */
877int
878getbound(tp)
879	type_t	*tp;
880{
881	int	a;
882	tspec_t	t;
883
884	while (tp->t_tspec == ARRAY)
885		tp = tp->t_subt;
886
887	if ((t = tp->t_tspec) == STRUCT || t == UNION) {
888		a = tp->t_str->align;
889	} else if (t == FUNC) {
890		/* compiler takes alignment of function */
891		error(14);
892		a = ALIGN(1) * CHAR_BIT;
893	} else {
894		if ((a = size(t)) == 0) {
895			a = CHAR_BIT;
896		} else if (a > ALIGN(1) * CHAR_BIT) {
897			a = ALIGN(1) * CHAR_BIT;
898		}
899	}
900	if (a < CHAR_BIT || a > ALIGN(1) * CHAR_BIT)
901		lerror("getbound() 1");
902	return (a);
903}
904
905/*
906 * Concatenate two lists of symbols by s_nxt. Used by declarations of
907 * struct/union/enum elements and parameters.
908 */
909sym_t *
910lnklst(l1, l2)
911	sym_t	*l1, *l2;
912{
913	sym_t	*l;
914
915	if ((l = l1) == NULL)
916		return (l2);
917	while (l1->s_nxt != NULL)
918		l1 = l1->s_nxt;
919	l1->s_nxt = l2;
920	return (l);
921}
922
923/*
924 * Check if the type of the given symbol is valid and print an error
925 * message if it is not.
926 *
927 * Invalid types are:
928 * - arrays of incomlete types or functions
929 * - functions returning arrays or functions
930 * - void types other than type of function or pointer
931 */
932void
933chktyp(sym)
934	sym_t	*sym;
935{
936	tspec_t	to, t;
937	type_t	**tpp, *tp;
938
939	tpp = &sym->s_type;
940	to = NOTSPEC;
941	while ((tp = *tpp) != NULL) {
942		t = tp->t_tspec;
943		/*
944		 * If this is the type of an old style function definition,
945		 * a better warning is printed in funcdef().
946		 */
947		if (t == FUNC && !tp->t_proto &&
948		    !(to == NOTSPEC && sym->s_osdef)) {
949			if (sflag && hflag)
950				/* function declaration is not a prototype */
951				warning(287);
952		}
953		if (to == FUNC) {
954			if (t == FUNC || t == ARRAY) {
955				/* function returns illegal type */
956				error(15);
957				if (t == FUNC) {
958					*tpp = incref(*tpp, PTR);
959				} else {
960					*tpp = incref((*tpp)->t_subt, PTR);
961				}
962				return;
963			} else if (tp->t_const || tp->t_volatile) {
964				if (sflag) {	/* XXX oder better !tflag ? */
965					/* function cannot return const... */
966					warning(228);
967				}
968			}
969		} if (to == ARRAY) {
970			if (t == FUNC) {
971				/* array of function is illegal */
972				error(16);
973				*tpp = gettyp(INT);
974				return;
975			} else if (t == ARRAY && tp->t_dim == 0) {
976				/* null dimension */
977				error(17);
978				return;
979			} else if (t == VOID) {
980				/* illegal use of void */
981				error(18);
982				*tpp = gettyp(INT);
983#if 0	/* errors are produced by length() */
984			} else if (incompl(tp)) {
985				/* array of incomplete type */
986				if (sflag) {
987					error(301);
988				} else {
989					warning(301);
990				}
991#endif
992			}
993		} else if (to == NOTSPEC && t == VOID) {
994			if (dcs->d_ctx == PARG) {
995				if (sym->s_scl != ABSTRACT) {
996					if (sym->s_name == unnamed)
997						lerror("chktyp()");
998					/* void param cannot have name: %s */
999					error(61, sym->s_name);
1000					*tpp = gettyp(INT);
1001				}
1002			} else if (dcs->d_ctx == ABSTRACT) {
1003				/* ok */
1004			} else if (sym->s_scl != TYPEDEF) {
1005				/* void type for %s */
1006				error(19, sym->s_name);
1007				*tpp = gettyp(INT);
1008			}
1009		}
1010		if (t == VOID && to != PTR) {
1011			if (tp->t_const || tp->t_volatile) {
1012				/* inappropriate qualifiers with "void" */
1013				warning(69);
1014				tp->t_const = tp->t_volatile = 0;
1015			}
1016		}
1017		tpp = &tp->t_subt;
1018		to = t;
1019	}
1020}
1021
1022/*
1023 * Process the declarator of a struct/union element.
1024 */
1025sym_t *
1026decl1str(dsym)
1027	sym_t	*dsym;
1028{
1029	type_t	*tp;
1030	tspec_t	t;
1031	int	sz, o, len;
1032	scl_t	sc;
1033
1034	if ((sc = dsym->s_scl) != MOS && sc != MOU)
1035		lerror("decl1str() 1");
1036
1037	if (dcs->d_rdcsym != NULL) {
1038		if ((sc = dcs->d_rdcsym->s_scl) != MOS && sc != MOU)
1039			/* should be ensured by storesym() */
1040			lerror("decl1str() 2");
1041		if (dsym->s_styp == dcs->d_rdcsym->s_styp) {
1042			/* duplicate member name: %s */
1043			error(33, dsym->s_name);
1044			rmsym(dcs->d_rdcsym);
1045		}
1046	}
1047
1048	chktyp(dsym);
1049
1050	t = (tp = dsym->s_type)->t_tspec;
1051
1052	if (dsym->s_field) {
1053		/*
1054		 * bit field
1055		 *
1056		 * only unsigned und signed int are protable bit-field types
1057		 *(at least in ANSI C, in traditional C only unsigned int)
1058		 */
1059		if (t == CHAR || t == UCHAR || t == SCHAR ||
1060		    t == SHORT || t == USHORT || t == ENUM) {
1061			if (sflag) {
1062				/* bit-field type '%s' invalid in ANSI C */
1063				warning(273, tyname(tp));
1064			} else if (pflag) {
1065				/* nonportable bit-field type */
1066				warning(34);
1067			}
1068		} else if (t == INT && dcs->d_smod == NOTSPEC) {
1069			if (pflag) {
1070				/* nonportable bit-field type */
1071				warning(34);
1072			}
1073		} else if (t != INT && t != UINT) {
1074			/* illegal bit-field type */
1075			error(35);
1076			sz = tp->t_flen;
1077			dsym->s_type = tp = duptyp(gettyp(t = INT));
1078			if ((tp->t_flen = sz) > size(t))
1079				tp->t_flen = size(t);
1080		}
1081		if ((len = tp->t_flen) < 0 || len > size(t)) {
1082			/* illegal bit-field size */
1083			error(36);
1084			tp->t_flen = size(t);
1085		} else if (len == 0 && dsym->s_name != unnamed) {
1086			/* zero size bit-field */
1087			error(37);
1088			tp->t_flen = size(t);
1089		}
1090		if (dsym->s_scl == MOU) {
1091			/* illegal use of bit-field */
1092			error(41);
1093			dsym->s_type->t_isfield = 0;
1094			dsym->s_field = 0;
1095		}
1096	} else if (t == FUNC) {
1097		/* function illegal in structure or union */
1098		error(38);
1099		dsym->s_type = tp = incref(tp, t = PTR);
1100	}
1101
1102	/*
1103	 * bit-fields of length 0 are not warned about because length()
1104	 * does not return the length of the bit-field but the length
1105	 * of the type the bit-field is packed in (its ok)
1106	 */
1107	if ((sz = length(dsym->s_type, dsym->s_name)) == 0) {
1108		if (t == ARRAY && dsym->s_type->t_dim == 0) {
1109			/* illegal zero sized structure member: %s */
1110			warning(39, dsym->s_name);
1111		}
1112	}
1113
1114	if (dcs->d_ctx == MOU) {
1115		o = dcs->d_offset;
1116		dcs->d_offset = 0;
1117	}
1118	if (dsym->s_field) {
1119		align(getbound(tp), tp->t_flen);
1120		dsym->s_value.v_quad = (dcs->d_offset / size(t)) * size(t);
1121		tp->t_foffs = dcs->d_offset - (int)dsym->s_value.v_quad;
1122		dcs->d_offset += tp->t_flen;
1123	} else {
1124		align(getbound(tp), 0);
1125		dsym->s_value.v_quad = dcs->d_offset;
1126		dcs->d_offset += sz;
1127	}
1128	if (dcs->d_ctx == MOU) {
1129		if (o > dcs->d_offset)
1130			dcs->d_offset = o;
1131	}
1132
1133	chkfdef(dsym, 0);
1134
1135	return (dsym);
1136}
1137
1138/*
1139 * Aligns next structure element as required.
1140 *
1141 * al contains the required alignment, len the length of a bit-field.
1142 */
1143static void
1144align(al, len)
1145	int	al, len;
1146{
1147	int	no;
1148
1149	/*
1150	 * The alignment of the current element becomes the alignment of
1151	 * the struct/union if it is larger than the current alignment
1152	 * of the struct/union.
1153	 */
1154	if (al > dcs->d_stralign)
1155		dcs->d_stralign = al;
1156
1157	no = (dcs->d_offset + (al - 1)) & ~(al - 1);
1158	if (len == 0 || dcs->d_offset + len > no)
1159		dcs->d_offset = no;
1160}
1161
1162/*
1163 * Remember the width of the field in its type structure.
1164 */
1165sym_t *
1166bitfield(dsym, len)
1167	sym_t	*dsym;
1168	int	len;
1169{
1170	if (dsym == NULL) {
1171		dsym = getblk(sizeof (sym_t));
1172		dsym->s_name = unnamed;
1173		dsym->s_kind = FMOS;
1174		dsym->s_scl = MOS;
1175		dsym->s_type = gettyp(INT);
1176		dsym->s_blklev = -1;
1177	}
1178	dsym->s_type = duptyp(dsym->s_type);
1179	dsym->s_type->t_isfield = 1;
1180	dsym->s_type->t_flen = len;
1181	dsym->s_field = 1;
1182	return (dsym);
1183}
1184
1185/*
1186 * Collect informations about a sequence of asterisks and qualifiers
1187 * in a list of type pqinf_t.
1188 * Qualifiers refer always to the left asterisk. The rightmost asterisk
1189 * will be at the top of the list.
1190 */
1191pqinf_t *
1192mergepq(p1, p2)
1193	pqinf_t	*p1, *p2;
1194{
1195	pqinf_t	*p;
1196
1197	if (p2->p_pcnt != 0) {
1198		/* left '*' at the end of the list */
1199		for (p = p2; p->p_nxt != NULL; p = p->p_nxt) ;
1200		p->p_nxt = p1;
1201		return (p2);
1202	} else {
1203		if (p2->p_const) {
1204			if (p1->p_const) {
1205				/* duplicate %s */
1206				warning(10, "const");
1207			}
1208			p1->p_const = 1;
1209		}
1210		if (p2->p_volatile) {
1211			if (p1->p_volatile) {
1212				/* duplicate %s */
1213				warning(10, "volatile");
1214			}
1215			p1->p_volatile = 1;
1216		}
1217		free(p2);
1218		return (p1);
1219	}
1220}
1221
1222/*
1223 * Followint 3 functions extend the type of a declarator with
1224 * pointer, function and array types.
1225 *
1226 * The current type is the Type built by deftyp() (dcs->d_type) and
1227 * pointer, function and array types already added for this
1228 * declarator. The new type extension is inserted between both.
1229 */
1230sym_t *
1231addptr(decl, pi)
1232	sym_t	*decl;
1233	pqinf_t	*pi;
1234{
1235	type_t	**tpp, *tp;
1236	pqinf_t	*npi;
1237
1238	tpp = &decl->s_type;
1239	while (*tpp != dcs->d_type)
1240		tpp = &(*tpp)->t_subt;
1241
1242	while (pi != NULL) {
1243		*tpp = tp = getblk(sizeof (type_t));
1244		tp->t_tspec = PTR;
1245		tp->t_const = pi->p_const;
1246		tp->t_volatile = pi->p_volatile;
1247		*(tpp = &tp->t_subt) = dcs->d_type;
1248		npi = pi->p_nxt;
1249		free(pi);
1250		pi = npi;
1251	}
1252	return (decl);
1253}
1254
1255/*
1256 * If a dimension was specified, dim is 1, otherwise 0
1257 * n is the specified dimension
1258 */
1259sym_t *
1260addarray(decl, dim, n)
1261	sym_t	*decl;
1262	int	dim, n;
1263{
1264	type_t	**tpp, *tp;
1265
1266	tpp = &decl->s_type;
1267	while (*tpp != dcs->d_type)
1268		tpp = &(*tpp)->t_subt;
1269
1270	*tpp = tp = getblk(sizeof (type_t));
1271	tp->t_tspec = ARRAY;
1272	tp->t_subt = dcs->d_type;
1273	tp->t_dim = n;
1274
1275	if (n < 0) {
1276		/* zero or negative array dimension */
1277		error(20);
1278		n = 0;
1279	} else if (n == 0 && dim) {
1280		/* zero or negative array dimension */
1281		warning(20);
1282	} else if (n == 0 && !dim) {
1283		/* is incomplete type */
1284		setcompl(tp, 1);
1285	}
1286
1287	return (decl);
1288}
1289
1290sym_t *
1291addfunc(decl, args)
1292	sym_t	*decl, *args;
1293{
1294	type_t	**tpp, *tp;
1295
1296	if (dcs->d_proto) {
1297		if (tflag)
1298			/* function prototypes are illegal in traditional C */
1299			warning(270);
1300		args = nsfunc(decl, args);
1301	} else {
1302		osfunc(decl, args);
1303	}
1304
1305	/*
1306	 * The symbols are removed from the symbol table by popdecl() after
1307	 * addfunc(). To be able to restore them if this is a function
1308	 * definition, a pointer to the list of all symbols is stored in
1309	 * dcs->d_nxt->d_fpsyms. Also a list of the arguments (concatenated
1310	 * by s_nxt) is stored in dcs->d_nxt->d_fargs.
1311	 * (dcs->d_nxt must be used because *dcs is the declaration stack
1312	 * element created for the list of params and is removed after
1313	 * addfunc())
1314	 */
1315	if (dcs->d_nxt->d_ctx == EXTERN &&
1316	    decl->s_type == dcs->d_nxt->d_type) {
1317		dcs->d_nxt->d_fpsyms = dcs->d_dlsyms;
1318		dcs->d_nxt->d_fargs = args;
1319	}
1320
1321	tpp = &decl->s_type;
1322	while (*tpp != dcs->d_nxt->d_type)
1323		tpp = &(*tpp)->t_subt;
1324
1325	*tpp = tp = getblk(sizeof (type_t));
1326	tp->t_tspec = FUNC;
1327	tp->t_subt = dcs->d_nxt->d_type;
1328	if ((tp->t_proto = dcs->d_proto) != 0)
1329		tp->t_args = args;
1330	tp->t_vararg = dcs->d_vararg;
1331
1332	return (decl);
1333}
1334
1335/*
1336 * Called for new style function declarations.
1337 */
1338/* ARGSUSED */
1339static sym_t *
1340nsfunc(decl, args)
1341	sym_t	*decl, *args;
1342{
1343	sym_t	*arg, *sym;
1344	scl_t	sc;
1345	int	n;
1346
1347	/*
1348	 * Declarations of structs/unions/enums in param lists are legal,
1349	 * but senseless.
1350	 */
1351	for (sym = dcs->d_dlsyms; sym != NULL; sym = sym->s_dlnxt) {
1352		sc = sym->s_scl;
1353		if (sc == STRTAG || sc == UNIONTAG || sc == ENUMTAG) {
1354			/* dubious tag declaration: %s %s */
1355			warning(85, scltoa(sc), sym->s_name);
1356		}
1357	}
1358
1359	n = 1;
1360	for (arg = args; arg != NULL; arg = arg->s_nxt) {
1361		if (arg->s_type->t_tspec == VOID) {
1362			if (n > 1 || arg->s_nxt != NULL) {
1363				/* "void" must be sole parameter */
1364				error(60);
1365				arg->s_type = gettyp(INT);
1366			}
1367		}
1368		n++;
1369	}
1370
1371	/* return NULL if first param is VOID */
1372	return (args != NULL && args->s_type->t_tspec != VOID ? args : NULL);
1373}
1374
1375/*
1376 * Called for old style function declarations.
1377 */
1378static void
1379osfunc(decl, args)
1380	sym_t	*decl, *args;
1381{
1382	/*
1383	 * Remember list of params only if this is really seams to be
1384	 * a function definition.
1385	 */
1386	if (dcs->d_nxt->d_ctx == EXTERN &&
1387	    decl->s_type == dcs->d_nxt->d_type) {
1388		/*
1389		 * We assume that this becomes a function definition. If
1390		 * we are wrong, its corrected in chkfdef().
1391		 */
1392		if (args != NULL) {
1393			decl->s_osdef = 1;
1394			decl->s_args = args;
1395		}
1396	} else {
1397		if (args != NULL)
1398			/* function prototype parameters must have types */
1399			warning(62);
1400	}
1401}
1402
1403/*
1404 * Lists of Identifiers in functions declarations are allowed only if
1405 * its also a function definition. If this is not the case, print a
1406 * error message.
1407 */
1408void
1409chkfdef(sym, msg)
1410	sym_t	*sym;
1411	int	msg;
1412{
1413	if (sym->s_osdef) {
1414		if (msg) {
1415			/* incomplete or misplaced function definition */
1416			error(22);
1417		}
1418		sym->s_osdef = 0;
1419		sym->s_args = NULL;
1420	}
1421}
1422
1423/*
1424 * Process the name in a declarator.
1425 * If the symbol does already exists, a new one is created.
1426 * The symbol becomes one of the storage classes EXTERN, STATIC, AUTO or
1427 * TYPEDEF.
1428 * s_def and s_reg are valid after dname().
1429 */
1430sym_t *
1431dname(sym)
1432	sym_t	*sym;
1433{
1434	scl_t	sc;
1435
1436	if (sym->s_scl == NOSCL) {
1437		dcs->d_rdcsym = NULL;
1438	} else if (sym->s_defarg) {
1439		sym->s_defarg = 0;
1440		dcs->d_rdcsym = NULL;
1441	} else {
1442		dcs->d_rdcsym = sym;
1443		sym = pushdown(sym);
1444	}
1445
1446	switch (dcs->d_ctx) {
1447	case MOS:
1448	case MOU:
1449		/* Parent setzen */
1450		sym->s_styp = dcs->d_tagtyp->t_str;
1451		sym->s_def = DEF;
1452		sym->s_value.v_tspec = INT;
1453		sc = dcs->d_ctx;
1454		break;
1455	case EXTERN:
1456		/*
1457		 * static and external symbols without "extern" are
1458		 * considered to be tentative defined, external
1459		 * symbols with "extern" are declared, and typedef names
1460		 * are defined. Tentative defined and declared symbols
1461		 * may become defined if an initializer is present or
1462		 * this is a function definition.
1463		 */
1464		if ((sc = dcs->d_scl) == NOSCL) {
1465			sc = EXTERN;
1466			sym->s_def = TDEF;
1467		} else if (sc == STATIC) {
1468			sym->s_def = TDEF;
1469		} else if (sc == TYPEDEF) {
1470			sym->s_def = DEF;
1471		} else if (sc == EXTERN) {
1472			sym->s_def = DECL;
1473		} else {
1474			lerror("dname() 1");
1475		}
1476		break;
1477	case PARG:
1478		sym->s_arg = 1;
1479		/* FALLTHROUGH */
1480	case ARG:
1481		if ((sc = dcs->d_scl) == NOSCL) {
1482			sc = AUTO;
1483		} else if (sc == REG) {
1484			sym->s_reg = 1;
1485			sc = AUTO;
1486		} else {
1487			lerror("dname() 2");
1488		}
1489		sym->s_def = DEF;
1490		break;
1491	case AUTO:
1492		if ((sc = dcs->d_scl) == NOSCL) {
1493			/*
1494			 * XXX somewhat ugly because we dont know whether
1495			 * this is AUTO or EXTERN (functions). If we are
1496			 * wrong it must be corrected in decl1loc(), where
1497			 * we have the neccessary type information.
1498			 */
1499			sc = AUTO;
1500			sym->s_def = DEF;
1501		} else if (sc == AUTO || sc == STATIC || sc == TYPEDEF) {
1502			sym->s_def = DEF;
1503		} else if (sc == REG) {
1504			sym->s_reg = 1;
1505			sc = AUTO;
1506			sym->s_def = DEF;
1507		} else if (sc == EXTERN) {
1508			sym->s_def = DECL;
1509		} else {
1510			lerror("dname() 3");
1511		}
1512		break;
1513	default:
1514		lerror("dname() 4");
1515	}
1516	sym->s_scl = sc;
1517
1518	sym->s_type = dcs->d_type;
1519
1520	dcs->d_fpsyms = NULL;
1521
1522	return (sym);
1523}
1524
1525/*
1526 * Process a name in the list of formal params in an old style function
1527 * definition.
1528 */
1529sym_t *
1530iname(sym)
1531	sym_t	*sym;
1532{
1533	if (sym->s_scl != NOSCL) {
1534		if (blklev == sym->s_blklev) {
1535			/* redeclaration of formal parameter %s */
1536			error(21, sym->s_name);
1537			if (!sym->s_defarg)
1538				lerror("iname()");
1539		}
1540		sym = pushdown(sym);
1541	}
1542	sym->s_type = gettyp(INT);
1543	sym->s_scl = AUTO;
1544	sym->s_def = DEF;
1545	sym->s_defarg = sym->s_arg = 1;
1546	return (sym);
1547}
1548
1549/*
1550 * Create the type of a tag.
1551 *
1552 * tag points to the symbol table entry of the tag
1553 * kind is the kind of the tag (STRUCT/UNION/ENUM)
1554 * decl is 1 if the type of the tag will be completed in this declaration
1555 * (the following token is T_LBRACE)
1556 * semi is 1 if the following token is T_SEMI
1557 */
1558type_t *
1559mktag(tag, kind, decl, semi)
1560	sym_t	*tag;
1561	tspec_t	kind;
1562	int	decl, semi;
1563{
1564	scl_t	scl;
1565	type_t	*tp;
1566
1567	if (kind == STRUCT) {
1568		scl = STRTAG;
1569	} else if (kind == UNION) {
1570		scl = UNIONTAG;
1571	} else if (kind == ENUM) {
1572		scl = ENUMTAG;
1573	} else {
1574		lerror("mktag()");
1575	}
1576
1577	if (tag != NULL) {
1578		if (tag->s_scl != NOSCL) {
1579			tag = newtag(tag, scl, decl, semi);
1580		} else {
1581			/* a new tag, no empty declaration */
1582			dcs->d_nxt->d_nedecl = 1;
1583			if (scl == ENUMTAG && !decl) {
1584				if (!tflag && (sflag || pflag))
1585					/* forward reference to enum type */
1586					warning(42);
1587			}
1588		}
1589		if (tag->s_scl == NOSCL) {
1590			tag->s_scl = scl;
1591			tag->s_type = tp = getblk(sizeof (type_t));
1592		} else {
1593			tp = tag->s_type;
1594		}
1595	} else {
1596		tag = getblk(sizeof (sym_t));
1597		tag->s_name = unnamed;
1598		STRUCT_ASSIGN(tag->s_dpos, curr_pos);
1599		tag->s_kind = FTAG;
1600		tag->s_scl = scl;
1601		tag->s_blklev = -1;
1602		tag->s_type = tp = getblk(sizeof (type_t));
1603		dcs->d_nxt->d_nedecl = 1;
1604	}
1605
1606	if (tp->t_tspec == NOTSPEC) {
1607		tp->t_tspec = kind;
1608		if (kind != ENUM) {
1609			tp->t_str = getblk(sizeof (str_t));
1610			tp->t_str->align = CHAR_BIT;
1611			tp->t_str->stag = tag;
1612		} else {
1613			tp->t_isenum = 1;
1614			tp->t_enum = getblk(sizeof (enum_t));
1615			tp->t_enum->etag = tag;
1616		}
1617		/* ist unvollstaendiger Typ */
1618		setcompl(tp, 1);
1619	}
1620
1621	return (tp);
1622}
1623
1624/*
1625 * Checks all possible cases of tag redeclarations.
1626 * decl is 1 if T_LBRACE follows
1627 * semi is 1 if T_SEMI follows
1628 */
1629static sym_t *
1630newtag(tag, scl, decl, semi)
1631	sym_t	*tag;
1632	scl_t	scl;
1633	int	decl, semi;
1634{
1635	if (tag->s_blklev < blklev) {
1636		if (semi) {
1637			/* "struct a;" */
1638			if (!tflag) {
1639				if (!sflag)
1640					/* decl. introduces new type ... */
1641					warning(44, scltoa(scl), tag->s_name);
1642				tag = pushdown(tag);
1643			} else if (tag->s_scl != scl) {
1644				/* base type is really "%s %s" */
1645				warning(45, scltoa(tag->s_scl), tag->s_name);
1646			}
1647			dcs->d_nxt->d_nedecl = 1;
1648		} else if (decl) {
1649			/* "struct a { ..." */
1650			if (hflag)
1651				/* redefinition hides earlier one: %s */
1652				warning(43, tag->s_name);
1653			tag = pushdown(tag);
1654			dcs->d_nxt->d_nedecl = 1;
1655		} else if (tag->s_scl != scl) {
1656			/* base type is really "%s %s" */
1657			warning(45, scltoa(tag->s_scl), tag->s_name);
1658			/* declaration introduces new type in ANSI C: %s %s */
1659			if (!sflag)
1660				warning(44, scltoa(scl), tag->s_name);
1661			tag = pushdown(tag);
1662			dcs->d_nxt->d_nedecl = 1;
1663		}
1664	} else {
1665		if (tag->s_scl != scl) {
1666			/* (%s) tag redeclared */
1667			error(46, scltoa(tag->s_scl));
1668			prevdecl(-1, tag);
1669			tag = pushdown(tag);
1670			dcs->d_nxt->d_nedecl = 1;
1671		} else if (decl && !incompl(tag->s_type)) {
1672			/* (%s) tag redeclared */
1673			error(46, scltoa(tag->s_scl));
1674			prevdecl(-1, tag);
1675			tag = pushdown(tag);
1676			dcs->d_nxt->d_nedecl = 1;
1677		} else if (semi || decl) {
1678			dcs->d_nxt->d_nedecl = 1;
1679		}
1680	}
1681	return (tag);
1682}
1683
1684const char *
1685scltoa(sc)
1686	scl_t	sc;
1687{
1688	const	char *s;
1689
1690	switch (sc) {
1691	case EXTERN:	s = "extern";	break;
1692	case STATIC:	s = "static";	break;
1693	case AUTO:	s = "auto";	break;
1694	case REG:	s = "register";	break;
1695	case TYPEDEF:	s = "typedef";	break;
1696	case STRTAG:	s = "struct";	break;
1697	case UNIONTAG:	s = "union";	break;
1698	case ENUMTAG:	s = "enum";	break;
1699	default:	lerror("tagttoa()");
1700	}
1701	return (s);
1702}
1703
1704/*
1705 * Completes the type of a tag in a struct/union/enum declaration.
1706 * tp points to the type of the, tag, fmem to the list of members/enums.
1707 */
1708type_t *
1709compltag(tp, fmem)
1710	type_t	*tp;
1711	sym_t	*fmem;
1712{
1713	tspec_t	t;
1714	str_t	*sp;
1715	int	n;
1716	sym_t	*mem;
1717
1718	/* from now a complete type */
1719	setcompl(tp, 0);
1720
1721	if ((t = tp->t_tspec) != ENUM) {
1722		align(dcs->d_stralign, 0);
1723		sp = tp->t_str;
1724		sp->align = dcs->d_stralign;
1725		sp->size = dcs->d_offset;
1726		sp->memb = fmem;
1727		if (sp->size == 0) {
1728			/* zero sized %s */
1729			(void)gnuism(47, ttab[t].tt_name);
1730		} else {
1731			n = 0;
1732			for (mem = fmem; mem != NULL; mem = mem->s_nxt) {
1733				if (mem->s_name != unnamed)
1734					n++;
1735			}
1736			if (n == 0) {
1737				/* %s has no named members */
1738				warning(65,
1739					t == STRUCT ? "structure" : "union");
1740			}
1741		}
1742	} else {
1743		tp->t_enum->elem = fmem;
1744	}
1745	return (tp);
1746}
1747
1748/*
1749 * Processes the name of an enumerator in en enum declaration.
1750 *
1751 * sym points to the enumerator
1752 * val is the value of the enumerator
1753 * impl is 1 if the the value of the enumerator was not explicit specified.
1754 */
1755sym_t *
1756ename(sym, val, impl)
1757	sym_t	*sym;
1758	int	val, impl;
1759{
1760	if (sym->s_scl) {
1761		if (sym->s_blklev == blklev) {
1762			/* no hflag, because this is illegal!!! */
1763			if (sym->s_arg) {
1764				/* enumeration constant hides parameter: %s */
1765				warning(57, sym->s_name);
1766			} else {
1767				/* redeclaration of %s */
1768				error(27, sym->s_name);
1769				/*
1770				 * inside blocks it should not too complicated
1771				 * to find the position of the previous
1772				 * declaration
1773				 */
1774				if (blklev == 0)
1775					prevdecl(-1, sym);
1776			}
1777		} else {
1778			if (hflag)
1779				/* redefinition hides earlier one: %s */
1780				warning(43, sym->s_name);
1781		}
1782		sym = pushdown(sym);
1783	}
1784	sym->s_scl = ENUMCON;
1785	sym->s_type = dcs->d_tagtyp;
1786	sym->s_value.v_tspec = INT;
1787	sym->s_value.v_quad = val;
1788	if (impl && val - 1 == INT_MAX) {
1789		/* overflow in enumeration values: %s */
1790		warning(48, sym->s_name);
1791	}
1792	enumval = val + 1;
1793	return (sym);
1794}
1795
1796/*
1797 * Process a single external declarator.
1798 */
1799void
1800decl1ext(dsym, initflg)
1801	sym_t	*dsym;
1802	int	initflg;
1803{
1804	int	warn, rval, redec;
1805	sym_t	*rdsym;
1806
1807	chkfdef(dsym, 1);
1808
1809	chktyp(dsym);
1810
1811	if (initflg && !(initerr = chkinit(dsym)))
1812		dsym->s_def = DEF;
1813
1814	/*
1815	 * Declarations of functions are marked as "tentative" in dname().
1816	 * This is wrong because there are no tentative function
1817	 * definitions.
1818	 */
1819	if (dsym->s_type->t_tspec == FUNC && dsym->s_def == TDEF)
1820		dsym->s_def = DECL;
1821
1822	if (dcs->d_inline) {
1823		if (dsym->s_type->t_tspec == FUNC) {
1824			dsym->s_inline = 1;
1825		} else {
1826			/* variable declared inline: %s */
1827			warning(268, dsym->s_name);
1828		}
1829	}
1830
1831	/* Write the declaration into the output file */
1832	if (plibflg && llibflg &&
1833	    dsym->s_type->t_tspec == FUNC && dsym->s_type->t_proto) {
1834		/*
1835		 * With both LINTLIBRARY and PROTOLIB the prototyp is
1836		 * written as a function definition to the output file.
1837		 */
1838		rval = dsym->s_type->t_subt->t_tspec != VOID;
1839		outfdef(dsym, &dsym->s_dpos, rval, 0, NULL);
1840	} else {
1841		outsym(dsym, dsym->s_scl, dsym->s_def);
1842	}
1843
1844	if ((rdsym = dcs->d_rdcsym) != NULL) {
1845
1846		/*
1847		 * If the old symbol stems from a old style function definition
1848		 * we have remembered the params in rdsmy->s_args and compare
1849		 * them with the params of the prototype.
1850		 */
1851		if (rdsym->s_osdef && dsym->s_type->t_proto) {
1852			redec = chkosdef(rdsym, dsym);
1853		} else {
1854			redec = 0;
1855		}
1856
1857		if (!redec && !isredec(dsym, (warn = 0, &warn))) {
1858
1859			if (warn) {
1860				/* redeclaration of %s */
1861				(*(sflag ? error : warning))(27, dsym->s_name);
1862				prevdecl(-1, rdsym);
1863			}
1864
1865			/*
1866			 * Overtake the rememberd params if the new symbol
1867			 * is not a prototype.
1868			 */
1869			if (rdsym->s_osdef && !dsym->s_type->t_proto) {
1870				dsym->s_osdef = rdsym->s_osdef;
1871				dsym->s_args = rdsym->s_args;
1872				STRUCT_ASSIGN(dsym->s_dpos, rdsym->s_dpos);
1873			}
1874
1875			/*
1876			 * Remember the position of the declaration if the
1877			 * old symbol was a prototype and the new is not.
1878			 * Also remember the position if the old symbol
1879			 * was defined and the new is not.
1880			 */
1881			if (rdsym->s_type->t_proto && !dsym->s_type->t_proto) {
1882				STRUCT_ASSIGN(dsym->s_dpos, rdsym->s_dpos);
1883			} else if (rdsym->s_def == DEF && dsym->s_def != DEF) {
1884				STRUCT_ASSIGN(dsym->s_dpos, rdsym->s_dpos);
1885			}
1886
1887			/*
1888			 * Copy informations about usage of the name into
1889			 * the new symbol.
1890			 */
1891			cpuinfo(dsym, rdsym);
1892
1893			/* Once a name is defined, it remains defined. */
1894			if (rdsym->s_def == DEF)
1895				dsym->s_def = DEF;
1896
1897			/* once a function is inline, it remains inline */
1898			if (rdsym->s_inline)
1899				dsym->s_inline = 1;
1900
1901			compltyp(dsym, rdsym);
1902
1903		}
1904
1905		rmsym(rdsym);
1906	}
1907
1908	if (dsym->s_scl == TYPEDEF) {
1909		dsym->s_type = duptyp(dsym->s_type);
1910		dsym->s_type->t_typedef = 1;
1911		settdsym(dsym->s_type, dsym);
1912	}
1913
1914}
1915
1916/*
1917 * Copies informations about usage into a new symbol table entry of
1918 * the same symbol.
1919 */
1920void
1921cpuinfo(sym, rdsym)
1922	sym_t	*sym, *rdsym;
1923{
1924	sym->s_spos = rdsym->s_spos;
1925	sym->s_upos = rdsym->s_upos;
1926	sym->s_set = rdsym->s_set;
1927	sym->s_used = rdsym->s_used;
1928}
1929
1930/*
1931 * Prints an error and returns 1 if a symbol is redeclared/redefined.
1932 * Otherwise returns 0 and, in some cases of minor problems, prints
1933 * a warning.
1934 */
1935int
1936isredec(dsym, warn)
1937	sym_t	*dsym;
1938	int	*warn;
1939{
1940	sym_t	*rsym;
1941
1942	if ((rsym = dcs->d_rdcsym)->s_scl == ENUMCON) {
1943		/* redeclaration of %s */
1944		error(27, dsym->s_name);
1945		prevdecl(-1, rsym);
1946		return (1);
1947	}
1948	if (rsym->s_scl == TYPEDEF) {
1949		/* typedef redeclared: %s */
1950		error(89, dsym->s_name);
1951		prevdecl(-1, rsym);
1952		return (1);
1953	}
1954	if (dsym->s_scl == TYPEDEF) {
1955		/* redeclaration of %s */
1956		error(27, dsym->s_name);
1957		prevdecl(-1, rsym);
1958		return (1);
1959	}
1960	if (rsym->s_def == DEF && dsym->s_def == DEF) {
1961		/* redefinition of %s */
1962		error(28, dsym->s_name);
1963		prevdecl(-1, rsym);
1964		return(1);
1965	}
1966	if (!eqtype(rsym->s_type, dsym->s_type, 0, 0, warn)) {
1967		/* redeclaration of %s */
1968		error(27, dsym->s_name);
1969		prevdecl(-1, rsym);
1970		return(1);
1971	}
1972	if (rsym->s_scl == EXTERN && dsym->s_scl == EXTERN)
1973		return(0);
1974	if (rsym->s_scl == STATIC && dsym->s_scl == STATIC)
1975		return(0);
1976	if (rsym->s_scl == STATIC && dsym->s_def == DECL)
1977		return(0);
1978	if (rsym->s_scl == EXTERN && rsym->s_def == DEF) {
1979		/*
1980		 * All cases except "int a = 1; static int a;" are catched
1981		 * above with or without a warning
1982		 */
1983		/* redeclaration of %s */
1984		error(27, dsym->s_name);
1985		prevdecl(-1, rsym);
1986		return(1);
1987	}
1988	if (rsym->s_scl == EXTERN) {
1989		/* previously declared extern, becomes static: %s */
1990		warning(29, dsym->s_name);
1991		prevdecl(-1, rsym);
1992		return(0);
1993	}
1994	/*
1995	 * Now its on of:
1996	 * "static a; int a;", "static a; int a = 1;", "static a = 1; int a;"
1997	 */
1998	/* redeclaration of %s; ANSI C requires "static" */
1999	if (sflag) {
2000		warning(30, dsym->s_name);
2001		prevdecl(-1, rsym);
2002	}
2003	dsym->s_scl = STATIC;
2004	return (0);
2005}
2006
2007/*
2008 * Checks if two types are compatible. Returns 0 if not, otherwise 1.
2009 *
2010 * ignqual	ignore qualifiers of type; used for function params
2011 * promot	promote left type; used for comparison of params of
2012 *		old style function definitions with params of prototypes.
2013 * *warn	set to 1 if an old style function declaration is not
2014 *		compatible with a prototype
2015 */
2016int
2017eqtype(tp1, tp2, ignqual, promot, warn)
2018	type_t	*tp1, *tp2;
2019	int	ignqual, promot, *warn;
2020{
2021	tspec_t	t;
2022
2023	while (tp1 != NULL && tp2 != NULL) {
2024
2025		t = tp1->t_tspec;
2026		if (promot) {
2027			if (t == FLOAT) {
2028				t = DOUBLE;
2029			} else if (t == CHAR || t == SCHAR) {
2030				t = INT;
2031			} else if (t == UCHAR) {
2032				t = tflag ? UINT : INT;
2033			} else if (t == SHORT) {
2034				t = INT;
2035			} else if (t == USHORT) {
2036				/* CONSTCOND */
2037				t = INT_MAX < USHRT_MAX || tflag ? UINT : INT;
2038			}
2039		}
2040
2041		if (t != tp2->t_tspec)
2042			return (0);
2043
2044		if (tp1->t_const != tp2->t_const && !ignqual && !tflag)
2045			return (0);
2046
2047		if (tp1->t_volatile != tp2->t_volatile && !ignqual && !tflag)
2048			return (0);
2049
2050		if (t == STRUCT || t == UNION)
2051			return (tp1->t_str == tp2->t_str);
2052
2053		if (t == ARRAY && tp1->t_dim != tp2->t_dim) {
2054			if (tp1->t_dim != 0 && tp2->t_dim != 0)
2055				return (0);
2056		}
2057
2058		/* dont check prototypes for traditional */
2059		if (t == FUNC && !tflag) {
2060			if (tp1->t_proto && tp2->t_proto) {
2061				if (!eqargs(tp1, tp2, warn))
2062					return (0);
2063			} else if (tp1->t_proto) {
2064				if (!mnoarg(tp1, warn))
2065					return (0);
2066			} else if (tp2->t_proto) {
2067				if (!mnoarg(tp2, warn))
2068					return (0);
2069			}
2070		}
2071
2072		tp1 = tp1->t_subt;
2073		tp2 = tp2->t_subt;
2074		ignqual = promot = 0;
2075
2076	}
2077
2078	return (tp1 == tp2);
2079}
2080
2081/*
2082 * Compares the parameter types of two prototypes.
2083 */
2084static int
2085eqargs(tp1, tp2, warn)
2086	type_t	*tp1, *tp2;
2087	int	*warn;
2088{
2089	sym_t	*a1, *a2;
2090
2091	if (tp1->t_vararg != tp2->t_vararg)
2092		return (0);
2093
2094	a1 = tp1->t_args;
2095	a2 = tp2->t_args;
2096
2097	while (a1 != NULL && a2 != NULL) {
2098
2099		if (eqtype(a1->s_type, a2->s_type, 1, 0, warn) == 0)
2100			return (0);
2101
2102		a1 = a1->s_nxt;
2103		a2 = a2->s_nxt;
2104
2105	}
2106
2107	return (a1 == a2);
2108}
2109
2110/*
2111 * mnoarg() (matches functions with no argument type information)
2112 * returns 1 if all parameters of a prototype are compatible with
2113 * and old style function declaration.
2114 * This is the case if following conditions are met:
2115 *	1. the prototype must have a fixed number of parameters
2116 *	2. no parameter is of type float
2117 *	3. no parameter is converted to another type if integer promotion
2118 *	   is applied on it
2119 */
2120static int
2121mnoarg(tp, warn)
2122	type_t	*tp;
2123	int	*warn;
2124{
2125	sym_t	*arg;
2126	tspec_t	t;
2127
2128	if (tp->t_vararg) {
2129		if (warn != NULL)
2130			*warn = 1;
2131	}
2132	for (arg = tp->t_args; arg != NULL; arg = arg->s_nxt) {
2133		if ((t = arg->s_type->t_tspec) == FLOAT ||
2134		    t == CHAR || t == SCHAR || t == UCHAR ||
2135		    t == SHORT || t == USHORT) {
2136			if (warn != NULL)
2137				*warn = 1;
2138		}
2139	}
2140	return (1);
2141}
2142
2143/*
2144 * Compares a prototype declaration with the remembered arguments of
2145 * a previous old style function definition.
2146 */
2147static int
2148chkosdef(rdsym, dsym)
2149	sym_t	*rdsym, *dsym;
2150{
2151	sym_t	*args, *pargs, *arg, *parg;
2152	int	narg, nparg, n;
2153	int	warn, msg;
2154
2155	args = rdsym->s_args;
2156	pargs = dsym->s_type->t_args;
2157
2158	msg = 0;
2159
2160	narg = nparg = 0;
2161	for (arg = args; arg != NULL; arg = arg->s_nxt)
2162		narg++;
2163	for (parg = pargs; parg != NULL; parg = parg->s_nxt)
2164		nparg++;
2165	if (narg != nparg) {
2166		/* prototype does not match old-style definition */
2167		error(63);
2168		msg = 1;
2169		goto end;
2170	}
2171
2172	arg = args;
2173	parg = pargs;
2174	n = 1;
2175	while (narg--) {
2176		warn = 0;
2177		/*
2178		 * If it does not match due to promotion and sflag is
2179		 * not set we print only a warning.
2180		 */
2181		if (!eqtype(arg->s_type, parg->s_type, 1, 1, &warn) || warn) {
2182			/* prototype does not match old-style def., arg #%d */
2183			error(299, n);
2184			msg = 1;
2185		}
2186		arg = arg->s_nxt;
2187		parg = parg->s_nxt;
2188		n++;
2189	}
2190
2191 end:
2192	if (msg)
2193		/* old style definition */
2194		prevdecl(300, rdsym);
2195
2196	return (msg);
2197}
2198
2199/*
2200 * Complets a type by copying the dimension and prototype information
2201 * from a second compatible type.
2202 *
2203 * Following lines are legal:
2204 *  "typedef a[]; a b; a b[10]; a c; a c[20];"
2205 *  "typedef ft(); ft f; f(int); ft g; g(long);"
2206 * This means that, if a type is completed, the type structure must
2207 * be duplicated.
2208 */
2209void
2210compltyp(dsym, ssym)
2211	sym_t	*dsym, *ssym;
2212{
2213	type_t	**dstp, *src;
2214	type_t	*dst;
2215
2216	dstp = &dsym->s_type;
2217	src = ssym->s_type;
2218
2219	while ((dst = *dstp) != NULL) {
2220		if (src == NULL || dst->t_tspec != src->t_tspec)
2221			lerror("compltyp() 1");
2222		if (dst->t_tspec == ARRAY) {
2223			if (dst->t_dim == 0 && src->t_dim != 0) {
2224				*dstp = dst = duptyp(dst);
2225				dst->t_dim = src->t_dim;
2226				/* now a complete Typ */
2227				setcompl(dst, 0);
2228			}
2229		} else if (dst->t_tspec == FUNC) {
2230			if (!dst->t_proto && src->t_proto) {
2231				*dstp = dst = duptyp(dst);
2232				dst->t_proto = 1;
2233				dst->t_args = src->t_args;
2234			}
2235		}
2236		dstp = &dst->t_subt;
2237		src = src->t_subt;
2238	}
2239}
2240
2241/*
2242 * Completes the declaration of a single argument.
2243 */
2244sym_t *
2245decl1arg(sym, initflg)
2246	sym_t	*sym;
2247	int	initflg;
2248{
2249	tspec_t	t;
2250
2251	chkfdef(sym, 1);
2252
2253	chktyp(sym);
2254
2255	if (dcs->d_rdcsym != NULL && dcs->d_rdcsym->s_blklev == blklev) {
2256		/* redeclaration of formal parameter %s */
2257		error(237, sym->s_name);
2258		rmsym(dcs->d_rdcsym);
2259		sym->s_arg = 1;
2260	}
2261
2262	if (!sym->s_arg) {
2263		/* declared argument %s is missing */
2264		error(53, sym->s_name);
2265		sym->s_arg = 1;
2266	}
2267
2268	if (initflg) {
2269		/* cannot initialize parameter: %s */
2270		error(52, sym->s_name);
2271		initerr = 1;
2272	}
2273
2274	if ((t = sym->s_type->t_tspec) == ARRAY) {
2275		sym->s_type = incref(sym->s_type->t_subt, PTR);
2276	} else if (t == FUNC) {
2277		if (tflag)
2278			/* a function is declared as an argument: %s */
2279			warning(50, sym->s_name);
2280		sym->s_type = incref(sym->s_type, PTR);
2281	} else if (t == FLOAT) {
2282		if (tflag)
2283			sym->s_type = gettyp(DOUBLE);
2284	}
2285
2286	if (dcs->d_inline)
2287		/* argument declared inline: %s */
2288		warning(269, sym->s_name);
2289
2290	/*
2291	 * Arguments must have complete types. lengths() prints the needed
2292	 * error messages (null dimension is impossible because arrays are
2293	 * converted to pointers).
2294	 */
2295	if (sym->s_type->t_tspec != VOID)
2296		(void)length(sym->s_type, sym->s_name);
2297
2298	setsflg(sym);
2299
2300	return (sym);
2301}
2302
2303/*
2304 * Does some checks for lint directives which apply to functions.
2305 * Processes arguments in old style function definitions which default
2306 * to int.
2307 * Checks compatiblility of old style function definition with previous
2308 * prototype.
2309 */
2310void
2311cluparg()
2312{
2313	sym_t	*args, *arg, *pargs, *parg;
2314	int	narg, nparg, n, msg;
2315	tspec_t	t;
2316
2317	args = funcsym->s_args;
2318	pargs = funcsym->s_type->t_args;
2319
2320	/* check for illegal combinations of lint directives */
2321	if (prflstrg != -1 && scflstrg != -1) {
2322		/* can't be used together: ** PRINTFLIKE ** ** SCANFLIKE ** */
2323		warning(289);
2324		prflstrg = scflstrg = -1;
2325	}
2326	if (nvararg != -1 && (prflstrg != -1 || scflstrg != -1)) {
2327		/* dubious use of ** VARARGS ** with ** %s ** */
2328		warning(288, prflstrg != -1 ? "PRINTFLIKE" : "SCANFLIKE");
2329		nvararg = -1;
2330	}
2331
2332	/*
2333	 * check if the argument of a lint directive is compatible with the
2334	 * number of arguments.
2335	 */
2336	narg = 0;
2337	for (arg = dcs->d_fargs; arg != NULL; arg = arg->s_nxt)
2338		narg++;
2339	if (nargusg > narg) {
2340		/* argument number mismatch with directive: ** %s ** */
2341		warning(283, "ARGSUSED");
2342		nargusg = 0;
2343	}
2344	if (nvararg > narg) {
2345		/* argument number mismatch with directive: ** %s ** */
2346		warning(283, "VARARGS");
2347		nvararg = 0;
2348	}
2349	if (prflstrg > narg) {
2350		/* argument number mismatch with directive: ** %s ** */
2351		warning(283, "PRINTFLIKE");
2352		prflstrg = -1;
2353	} else if (prflstrg == 0) {
2354		prflstrg = -1;
2355	}
2356	if (scflstrg > narg) {
2357		/* argument number mismatch with directive: ** %s ** */
2358		warning(283, "SCANFLIKE");
2359		scflstrg = -1;
2360	} else if (scflstrg == 0) {
2361		scflstrg = -1;
2362	}
2363	if (prflstrg != -1 || scflstrg != -1) {
2364		narg = prflstrg != -1 ? prflstrg : scflstrg;
2365		arg = dcs->d_fargs;
2366		for (n = 1; n < narg; n++)
2367			arg = arg->s_nxt;
2368		if (arg->s_type->t_tspec != PTR ||
2369		    ((t = arg->s_type->t_subt->t_tspec) != CHAR &&
2370		     t != UCHAR && t != SCHAR)) {
2371			/* arg. %d must be 'char *' for PRINTFLIKE/SCANFLIKE */
2372			warning(293, narg);
2373			prflstrg = scflstrg = -1;
2374		}
2375	}
2376
2377	/*
2378	 * print a warning for each argument off an old style function
2379	 * definition which defaults to int
2380	 */
2381	for (arg = args; arg != NULL; arg = arg->s_nxt) {
2382		if (arg->s_defarg) {
2383			/* argument type defaults to int: %s */
2384			warning(32, arg->s_name);
2385			arg->s_defarg = 0;
2386			setsflg(arg);
2387		}
2388	}
2389
2390	/*
2391	 * If this is an old style function definition and a prototyp
2392	 * exists, compare the types of arguments.
2393	 */
2394	if (funcsym->s_osdef && funcsym->s_type->t_proto) {
2395		/*
2396		 * If the number of arguments does not macht, we need not
2397		 * continue.
2398		 */
2399		narg = nparg = 0;
2400		msg = 0;
2401		for (parg = pargs; parg != NULL; parg = parg->s_nxt)
2402			nparg++;
2403		for (arg = args; arg != NULL; arg = arg->s_nxt)
2404			narg++;
2405		if (narg != nparg) {
2406			/* parameter mismatch: %d declared, %d defined */
2407			error(51, nparg, narg);
2408			msg = 1;
2409		} else {
2410			parg = pargs;
2411			arg = args;
2412			while (narg--) {
2413				msg |= chkptdecl(arg, parg);
2414				parg = parg->s_nxt;
2415				arg = arg->s_nxt;
2416			}
2417		}
2418		if (msg)
2419			/* prototype declaration */
2420			prevdecl(285, dcs->d_rdcsym);
2421
2422		/* from now the prototype is valid */
2423		funcsym->s_osdef = 0;
2424		funcsym->s_args = NULL;
2425
2426	}
2427
2428}
2429
2430/*
2431 * Checks compatibility of an old style function definition with a previous
2432 * prototype declaration.
2433 * Returns 1 if the position of the previous declaration should be reported.
2434 */
2435static int
2436chkptdecl(arg, parg)
2437	sym_t	*arg, *parg;
2438{
2439	type_t	*tp, *ptp;
2440	int	warn, msg;
2441
2442	tp = arg->s_type;
2443	ptp = parg->s_type;
2444
2445	msg = 0;
2446	warn = 0;
2447
2448	if (!eqtype(tp, ptp, 1, 1, &warn)) {
2449		if (eqtype(tp, ptp, 1, 0, &warn)) {
2450			/* type does not match prototype: %s */
2451			msg = gnuism(58, arg->s_name);
2452		} else {
2453			/* type does not match prototype: %s */
2454			error(58, arg->s_name);
2455			msg = 1;
2456		}
2457	} else if (warn) {
2458		/* type does not match prototype: %s */
2459		(*(sflag ? error : warning))(58, arg->s_name);
2460		msg = 1;
2461	}
2462
2463	return (msg);
2464}
2465
2466/*
2467 * Completes a single local declaration/definition.
2468 */
2469void
2470decl1loc(dsym, initflg)
2471	sym_t	*dsym;
2472	int	initflg;
2473{
2474	/* Correct a mistake done in dname(). */
2475	if (dsym->s_type->t_tspec == FUNC) {
2476		dsym->s_def = DECL;
2477		if (dcs->d_scl == NOSCL)
2478			dsym->s_scl = EXTERN;
2479	}
2480
2481	if (dsym->s_type->t_tspec == FUNC) {
2482		if (dsym->s_scl == STATIC) {
2483			/* dubious static function at block level: %s */
2484			warning(93, dsym->s_name);
2485			dsym->s_scl = EXTERN;
2486		} else if (dsym->s_scl != EXTERN && dsym->s_scl != TYPEDEF) {
2487			/* function has illegal storage class: %s */
2488			error(94, dsym->s_name);
2489			dsym->s_scl = EXTERN;
2490		}
2491	}
2492
2493	/*
2494	 * functions may be declared inline at local scope, although
2495	 * this has no effect for a later definition of the same
2496	 * function.
2497	 * XXX it should have an effect if tflag is set. this would
2498	 * also be the way gcc behaves.
2499	 */
2500	if (dcs->d_inline) {
2501		if (dsym->s_type->t_tspec == FUNC) {
2502			dsym->s_inline = 1;
2503		} else {
2504			/* variable declared inline: %s */
2505			warning(268, dsym->s_name);
2506		}
2507	}
2508
2509	chkfdef(dsym, 1);
2510
2511	chktyp(dsym);
2512
2513	if (dcs->d_rdcsym != NULL && dsym->s_scl == EXTERN)
2514		ledecl(dsym);
2515
2516	if (dsym->s_scl == EXTERN) {
2517		/*
2518		 * XXX wenn die statische Variable auf Ebene 0 erst
2519		 * spaeter definiert wird, haben wir die Brille auf.
2520		 */
2521		if (dsym->s_xsym == NULL) {
2522			outsym(dsym, EXTERN, dsym->s_def);
2523		} else {
2524			outsym(dsym, dsym->s_xsym->s_scl, dsym->s_def);
2525		}
2526	}
2527
2528	if (dcs->d_rdcsym != NULL) {
2529
2530		if (dcs->d_rdcsym->s_blklev == 0) {
2531
2532			switch (dsym->s_scl) {
2533			case AUTO:
2534				/* automatic hides external declaration: %s */
2535				if (hflag)
2536					warning(86, dsym->s_name);
2537				break;
2538			case STATIC:
2539				/* static hides external declaration: %s */
2540				if (hflag)
2541					warning(87, dsym->s_name);
2542				break;
2543			case TYPEDEF:
2544				/* typedef hides  external declaration: %s */
2545				if (hflag)
2546					warning(88, dsym->s_name);
2547				break;
2548			case EXTERN:
2549				/*
2550				 * Warnings and errors are printed in ledecl()
2551				 */
2552				break;
2553			default:
2554				lerror("decl1loc() 1");
2555			}
2556
2557		} else if (dcs->d_rdcsym->s_blklev == blklev) {
2558
2559			/* no hflag, because its illegal! */
2560			if (dcs->d_rdcsym->s_arg) {
2561				/*
2562				 * if !tflag, a "redeclaration of %s" error
2563				 * is produced below
2564				 */
2565				if (tflag) {
2566					if (hflag)
2567						/* decl. hides parameter: %s */
2568						warning(91, dsym->s_name);
2569					rmsym(dcs->d_rdcsym);
2570				}
2571			}
2572
2573		} else if (dcs->d_rdcsym->s_blklev < blklev) {
2574
2575			if (hflag)
2576				/* declaration hides earlier one: %s */
2577				warning(95, dsym->s_name);
2578
2579		}
2580
2581		if (dcs->d_rdcsym->s_blklev == blklev) {
2582
2583			/* redeclaration of %s */
2584			error(27, dsym->s_name);
2585			rmsym(dcs->d_rdcsym);
2586
2587		}
2588
2589	}
2590
2591	if (initflg && !(initerr = chkinit(dsym))) {
2592		dsym->s_def = DEF;
2593		setsflg(dsym);
2594	}
2595
2596	if (dsym->s_scl == TYPEDEF) {
2597		dsym->s_type = duptyp(dsym->s_type);
2598		dsym->s_type->t_typedef = 1;
2599		settdsym(dsym->s_type, dsym);
2600	}
2601
2602	/*
2603	 * Before we can check the size we must wait for a initialisation
2604	 * which may follow.
2605	 */
2606}
2607
2608/*
2609 * Processes (re)declarations of external Symbols inside blocks.
2610 */
2611static void
2612ledecl(dsym)
2613	sym_t	*dsym;
2614{
2615	int	eqt, warn;
2616	sym_t	*esym;
2617
2618	/* look for a symbol with the same name */
2619	esym = dcs->d_rdcsym;
2620	while (esym != NULL && esym->s_blklev != 0) {
2621		while ((esym = esym->s_link) != NULL) {
2622			if (esym->s_kind != FVFT)
2623				continue;
2624			if (strcmp(dsym->s_name, esym->s_name) == 0)
2625				break;
2626		}
2627	}
2628	if (esym == NULL)
2629		return;
2630	if (esym->s_scl != EXTERN && esym->s_scl != STATIC) {
2631		/* gcc accepts this without a warning, pcc prints an error. */
2632		/* redeclaration of %s */
2633		warning(27, dsym->s_name);
2634		prevdecl(-1, esym);
2635		return;
2636	}
2637
2638	warn = 0;
2639	eqt = eqtype(esym->s_type, dsym->s_type, 0, 0, &warn);
2640
2641	if (!eqt || warn) {
2642		if (esym->s_scl == EXTERN) {
2643			/* inconsistent redeclaration of extern: %s */
2644			warning(90, dsym->s_name);
2645			prevdecl(-1, esym);
2646		} else {
2647			/* inconsistent redeclaration of static: %s */
2648			warning(92, dsym->s_name);
2649			prevdecl(-1, esym);
2650		}
2651	}
2652
2653	if (eqt) {
2654		/*
2655		 * Remember the external symbol so we can update usage
2656		 * information at the end of the block.
2657		 */
2658		dsym->s_xsym = esym;
2659	}
2660}
2661
2662/*
2663 * Print an error or a warning if the symbol cant be initialized due
2664 * to type/storage class. Returnvalue is 1 if an error has been
2665 * detected.
2666 */
2667static int
2668chkinit(sym)
2669	sym_t	*sym;
2670{
2671	int	err;
2672
2673	err = 0;
2674
2675	if (sym->s_type->t_tspec == FUNC) {
2676		/* cannot initialize function: %s */
2677		error(24, sym->s_name);
2678		err = 1;
2679	} else if (sym->s_scl == TYPEDEF) {
2680		/* cannot initialize typedef: %s */
2681		error(25, sym->s_name);
2682		err = 1;
2683	} else if (sym->s_scl == EXTERN && sym->s_def == DECL) {
2684		/* cannot initialize "extern" declaration: %s */
2685		if (dcs->d_ctx == EXTERN) {
2686			warning(26, sym->s_name);
2687		} else {
2688			error(26, sym->s_name);
2689			err = 1;
2690		}
2691	}
2692
2693	return (err);
2694}
2695
2696/*
2697 * Create a symbole for an abstract declaration.
2698 */
2699sym_t *
2700aname()
2701{
2702	sym_t	*sym;
2703
2704	if (dcs->d_ctx != ABSTRACT && dcs->d_ctx != PARG)
2705		lerror("aname()");
2706
2707	sym = getblk(sizeof (sym_t));
2708
2709	sym->s_name = unnamed;
2710	sym->s_def = DEF;
2711	sym->s_scl = ABSTRACT;
2712	sym->s_blklev = -1;
2713
2714	if (dcs->d_ctx == PARG)
2715		sym->s_arg = 1;
2716
2717	sym->s_type = dcs->d_type;
2718	dcs->d_rdcsym = NULL;
2719	dcs->d_vararg = 0;
2720
2721	return (sym);
2722}
2723
2724/*
2725 * Removes anything which has nothing to do on global level.
2726 */
2727void
2728globclup()
2729{
2730	while (dcs->d_nxt != NULL)
2731		popdecl();
2732
2733	cleanup();
2734	blklev = 0;
2735	mblklev = 0;
2736
2737	/*
2738	 * remove all informations about pending lint directives without
2739	 * warnings.
2740	 */
2741	glclup(1);
2742}
2743
2744/*
2745 * Process an abstract type declaration
2746 */
2747sym_t *
2748decl1abs(sym)
2749	sym_t	*sym;
2750{
2751	chkfdef(sym, 1);
2752	chktyp(sym);
2753	return (sym);
2754}
2755
2756/*
2757 * Checks size after declarations of variables and their initialisation.
2758 */
2759void
2760chksz(dsym)
2761	sym_t	*dsym;
2762{
2763	/*
2764	 * check size only for symbols which are defined and no function and
2765	 * not typedef name
2766	 */
2767	if (dsym->s_def != DEF)
2768		return;
2769	if (dsym->s_scl == TYPEDEF)
2770		return;
2771	if (dsym->s_type->t_tspec == FUNC)
2772		return;
2773
2774	if (length(dsym->s_type, dsym->s_name) == 0 &&
2775	    dsym->s_type->t_tspec == ARRAY && dsym->s_type->t_dim == 0) {
2776		/* empty array declaration: %s */
2777		if (tflag) {
2778			warning(190, dsym->s_name);
2779		} else {
2780			error(190, dsym->s_name);
2781		}
2782	}
2783}
2784
2785/*
2786 * Mark an object as set if it is not already
2787 */
2788void
2789setsflg(sym)
2790	sym_t	*sym;
2791{
2792	if (!sym->s_set) {
2793		sym->s_set = 1;
2794		STRUCT_ASSIGN(sym->s_spos, curr_pos);
2795	}
2796}
2797
2798/*
2799 * Mark an object as used if it is not already
2800 */
2801void
2802setuflg(sym, fcall, szof)
2803	sym_t	*sym;
2804	int	fcall, szof;
2805{
2806	if (!sym->s_used) {
2807		sym->s_used = 1;
2808		STRUCT_ASSIGN(sym->s_upos, curr_pos);
2809	}
2810	/*
2811	 * for function calls another record is written
2812	 *
2813	 * XXX Should symbols used in sizeof() treated as used or not?
2814	 * Probably not, because there is no sense to declare an
2815	 * external variable only to get their size.
2816	 */
2817	if (!fcall && !szof && sym->s_kind == FVFT && sym->s_scl == EXTERN)
2818		outusg(sym);
2819}
2820
2821/*
2822 * Prints warnings for a list of variables and labels (concatenated
2823 * with s_dlnxt) if these are not used or only set.
2824 */
2825void
2826chkusage(di)
2827	dinfo_t	*di;
2828{
2829	sym_t	*sym;
2830	int	mknowarn;
2831
2832	/* for this warnings LINTED has no effect */
2833	mknowarn = nowarn;
2834	nowarn = 0;
2835
2836	for (sym = di->d_dlsyms; sym != NULL; sym = sym->s_dlnxt)
2837		chkusg1(di->d_asm, sym);
2838
2839	nowarn = mknowarn;
2840}
2841
2842/*
2843 * Prints a warning for a single variable or label if it is not used or
2844 * only set.
2845 */
2846void
2847chkusg1(novar, sym)
2848	int	novar;
2849	sym_t	*sym;
2850{
2851	pos_t	cpos;
2852
2853	if (sym->s_blklev == -1)
2854		return;
2855
2856	STRUCT_ASSIGN(cpos, curr_pos);
2857
2858	if (sym->s_kind == FVFT) {
2859		if (sym->s_arg) {
2860			chkausg(novar, sym);
2861		} else {
2862			chkvusg(novar, sym);
2863		}
2864	} else if (sym->s_kind == FLAB) {
2865		chklusg(sym);
2866	} else if (sym->s_kind == FTAG) {
2867		chktusg(sym);
2868	}
2869
2870	STRUCT_ASSIGN(curr_pos, cpos);
2871}
2872
2873static void
2874chkausg(novar, arg)
2875	int	novar;
2876	sym_t	*arg;
2877{
2878	if (!arg->s_set)
2879		lerror("chkausg() 1");
2880
2881	if (novar)
2882		return;
2883
2884	if (!arg->s_used && vflag) {
2885		STRUCT_ASSIGN(curr_pos, arg->s_dpos);
2886		/* argument %s unused in function %s */
2887		warning(231, arg->s_name, funcsym->s_name);
2888	}
2889}
2890
2891static void
2892chkvusg(novar, sym)
2893	int	novar;
2894	sym_t	*sym;
2895{
2896	scl_t	sc;
2897	sym_t	*xsym;
2898
2899	if (blklev == 0 || sym->s_blklev == 0)
2900		lerror("chkvusg() 1");
2901
2902	/* errors in expressions easily cause lots of these warnings */
2903	if (nerr != 0)
2904		return;
2905
2906	/*
2907	 * XXX Only variables are checkd, although types should
2908	 * probably also be checked
2909	 */
2910	if ((sc = sym->s_scl) != EXTERN && sc != STATIC &&
2911	    sc != AUTO && sc != REG) {
2912		return;
2913	}
2914
2915	if (novar)
2916		return;
2917
2918	if (sc == EXTERN) {
2919		if (!sym->s_used && !sym->s_set) {
2920			STRUCT_ASSIGN(curr_pos, sym->s_dpos);
2921			/* %s unused in function %s */
2922			warning(192, sym->s_name, funcsym->s_name);
2923		}
2924	} else {
2925		if (sym->s_set && !sym->s_used) {
2926			STRUCT_ASSIGN(curr_pos, sym->s_spos);
2927			/* %s set but not used in function %s */
2928			warning(191, sym->s_name, funcsym->s_name);
2929		} else if (!sym->s_used) {
2930			STRUCT_ASSIGN(curr_pos, sym->s_dpos);
2931			/* %s unused in function %s */
2932			warning(192, sym->s_name, funcsym->s_name);
2933		}
2934	}
2935
2936	if (sc == EXTERN) {
2937		/*
2938		 * information about usage is taken over into the symbol
2939		 * tabel entry at level 0 if the symbol was locally declared
2940		 * as an external symbol.
2941		 *
2942		 * XXX This is wrong for symbols declared static at level 0
2943		 * if the usage information stems from sizeof(). This is
2944		 * because symbols at level 0 only used in sizeof() are
2945		 * considered to not be used.
2946		 */
2947		if ((xsym = sym->s_xsym) != NULL) {
2948			if (sym->s_used && !xsym->s_used) {
2949				xsym->s_used = 1;
2950				STRUCT_ASSIGN(xsym->s_upos, sym->s_upos);
2951			}
2952			if (sym->s_set && !xsym->s_set) {
2953				xsym->s_set = 1;
2954				STRUCT_ASSIGN(xsym->s_spos, sym->s_spos);
2955			}
2956		}
2957	}
2958}
2959
2960static void
2961chklusg(lab)
2962	sym_t	*lab;
2963{
2964	if (blklev != 1 || lab->s_blklev != 1)
2965		lerror("chklusg() 1");
2966
2967	if (lab->s_set && !lab->s_used) {
2968		STRUCT_ASSIGN(curr_pos, lab->s_spos);
2969		/* label %s unused in function %s */
2970		warning(192, lab->s_name, funcsym->s_name);
2971	} else if (!lab->s_set) {
2972		STRUCT_ASSIGN(curr_pos, lab->s_upos);
2973		/* undefined label %s */
2974		warning(23, lab->s_name);
2975	}
2976}
2977
2978static void
2979chktusg(sym)
2980	sym_t	*sym;
2981{
2982	if (!incompl(sym->s_type))
2983		return;
2984
2985	/* complain alwasy about incomplet tags declared inside blocks */
2986	if (!zflag || dcs->d_ctx != EXTERN)
2987		return;
2988
2989	STRUCT_ASSIGN(curr_pos, sym->s_dpos);
2990	switch (sym->s_type->t_tspec) {
2991	case STRUCT:
2992		/* struct %s never defined */
2993		warning(233, sym->s_name);
2994		break;
2995	case UNION:
2996		/* union %s never defined */
2997		warning(234, sym->s_name);
2998		break;
2999	case ENUM:
3000		/* enum %s never defined */
3001		warning(235, sym->s_name);
3002		break;
3003	default:
3004		lerror("chktusg() 1");
3005	}
3006}
3007
3008/*
3009 * Called after the entire translation unit has been parsed.
3010 * Changes tentative definitions in definitions.
3011 * Performs some tests on global Symbols. Detected Problems are:
3012 * - defined variables of incomplete type
3013 * - constant variables which are not initialized
3014 * - static symbols which are never used
3015 */
3016void
3017chkglsyms()
3018{
3019	sym_t	*sym;
3020	pos_t	cpos;
3021
3022	if (blklev != 0 || dcs->d_nxt != NULL)
3023		norecover();
3024
3025	STRUCT_ASSIGN(cpos, curr_pos);
3026
3027	for (sym = dcs->d_dlsyms; sym != NULL; sym = sym->s_dlnxt) {
3028		if (sym->s_blklev == -1)
3029			continue;
3030		if (sym->s_kind == FVFT) {
3031			chkglvar(sym);
3032		} else if (sym->s_kind == FTAG) {
3033			chktusg(sym);
3034		} else {
3035			if (sym->s_kind != FMOS)
3036				lerror("chkglsyms() 1");
3037		}
3038	}
3039
3040	STRUCT_ASSIGN(curr_pos, cpos);
3041}
3042
3043static void
3044chkglvar(sym)
3045	sym_t	*sym;
3046{
3047	if (sym->s_scl == TYPEDEF || sym->s_scl == ENUMCON)
3048		return;
3049
3050	if (sym->s_scl != EXTERN && sym->s_scl != STATIC)
3051		lerror("chkglvar() 1");
3052
3053	glchksz(sym);
3054
3055	if (sym->s_scl == STATIC) {
3056		if (sym->s_type->t_tspec == FUNC) {
3057			if (sym->s_used && sym->s_def != DEF) {
3058				STRUCT_ASSIGN(curr_pos, sym->s_upos);
3059				/* static func. called but not def.. */
3060				error(225, sym->s_name);
3061			}
3062		}
3063		if (!sym->s_used) {
3064			STRUCT_ASSIGN(curr_pos, sym->s_dpos);
3065			if (sym->s_type->t_tspec == FUNC) {
3066				if (sym->s_def == DEF) {
3067					if (!sym->s_inline)
3068						/* static function %s unused */
3069						warning(236, sym->s_name);
3070				} else {
3071					/* static function %s decl. but ... */
3072					warning(290, sym->s_name);
3073				}
3074			} else if (!sym->s_set) {
3075				/* static variable %s unused */
3076				warning(226, sym->s_name);
3077			} else {
3078				/* static variable %s set but not used */
3079				warning(307, sym->s_name);
3080			}
3081		}
3082		if (!tflag && sym->s_def == TDEF && sym->s_type->t_const) {
3083			STRUCT_ASSIGN(curr_pos, sym->s_dpos);
3084			/* const object %s should have initializer */
3085			warning(227, sym->s_name);
3086		}
3087	}
3088}
3089
3090static void
3091glchksz(sym)
3092	sym_t	*sym;
3093{
3094	if (sym->s_def == TDEF) {
3095		if (sym->s_type->t_tspec == FUNC)
3096			/*
3097			 * this can happen if an syntax error occured
3098			 * after a function declaration
3099			 */
3100			return;
3101		STRUCT_ASSIGN(curr_pos, sym->s_dpos);
3102		if (length(sym->s_type, sym->s_name) == 0 &&
3103		    sym->s_type->t_tspec == ARRAY && sym->s_type->t_dim == 0) {
3104			/* empty array declaration: %s */
3105			if (tflag || (sym->s_scl == EXTERN && !sflag)) {
3106				warning(190, sym->s_name);
3107			} else {
3108				error(190, sym->s_name);
3109			}
3110		}
3111	}
3112}
3113
3114/*
3115 * Prints information about location of previous definition/declaration.
3116 */
3117void
3118prevdecl(msg, psym)
3119	int	msg;
3120	sym_t	*psym;
3121{
3122	pos_t	cpos;
3123
3124	if (!rflag)
3125		return;
3126
3127	STRUCT_ASSIGN(cpos, curr_pos);
3128	STRUCT_ASSIGN(curr_pos, psym->s_dpos);
3129	if (msg != -1) {
3130		message(msg, psym->s_name);
3131	} else if (psym->s_def == DEF || psym->s_def == TDEF) {
3132		/* previous definition of %s */
3133		message(261, psym->s_name);
3134	} else {
3135		/* previous declaration of %s */
3136		message(260, psym->s_name);
3137	}
3138	STRUCT_ASSIGN(curr_pos, cpos);
3139}
3140