decl.c revision 75697
112099Sjoerg/*	$NetBSD: decl.c,v 1.11 1995/10/02 17:34:16 jpo Exp $	*/
212099Sjoerg
312099Sjoerg/*
412099Sjoerg * Copyright (c) 1994, 1995 Jochen Pohl
512099Sjoerg * All Rights Reserved.
612099Sjoerg *
712099Sjoerg * Redistribution and use in source and binary forms, with or without
812099Sjoerg * modification, are permitted provided that the following conditions
912099Sjoerg * are met:
1012099Sjoerg * 1. Redistributions of source code must retain the above copyright
1112099Sjoerg *    notice, this list of conditions and the following disclaimer.
1212099Sjoerg * 2. Redistributions in binary form must reproduce the above copyright
1312099Sjoerg *    notice, this list of conditions and the following disclaimer in the
1412099Sjoerg *    documentation and/or other materials provided with the distribution.
1512099Sjoerg * 3. All advertising materials mentioning features or use of this software
1612099Sjoerg *    must display the following acknowledgement:
1712099Sjoerg *      This product includes software developed by Jochen Pohl for
1812099Sjoerg *	The NetBSD Project.
1912099Sjoerg * 4. The name of the author may not be used to endorse or promote products
2012099Sjoerg *    derived from this software without specific prior written permission.
2112099Sjoerg *
2212099Sjoerg * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
2312099Sjoerg * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2412099Sjoerg * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2512099Sjoerg * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2612099Sjoerg * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2712099Sjoerg * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2812099Sjoerg * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2912099Sjoerg * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3012099Sjoerg * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
3112099Sjoerg * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3275697Sasmodai *
3375697Sasmodai * $FreeBSD: head/usr.bin/xlint/lint1/decl.c 75697 2001-04-19 11:10:51Z asmodai $
3412099Sjoerg */
3512099Sjoerg
3612099Sjoerg#ifndef lint
3712099Sjoergstatic char rcsid[] = "$NetBSD: decl.c,v 1.11 1995/10/02 17:34:16 jpo Exp $";
3812099Sjoerg#endif
3912099Sjoerg
4012099Sjoerg#include <sys/param.h>
4112099Sjoerg#include <limits.h>
4212099Sjoerg#include <stdlib.h>
4312099Sjoerg#include <string.h>
4412099Sjoerg
4512099Sjoerg#include "lint1.h"
4612099Sjoerg
4712099Sjoergconst	char *unnamed = "<unnamed>";
4812099Sjoerg
4912099Sjoerg/* contains various information and classification on types */
5012099Sjoergttab_t	ttab[NTSPEC];
5112099Sjoerg
5212099Sjoerg/* shared type structures for arithmtic types and void */
5312099Sjoergstatic	type_t	*typetab;
5412099Sjoerg
5512099Sjoerg/* value of next enumerator during declaration of enum types */
5612099Sjoergint	enumval;
5712099Sjoerg
5812099Sjoerg/*
5912099Sjoerg * pointer to top element of a stack which contains informations local
6012099Sjoerg * to nested declarations
6112099Sjoerg */
6212099Sjoergdinfo_t	*dcs;
6312099Sjoerg
6412099Sjoergstatic	type_t	*tdeferr __P((type_t *, tspec_t));
6512099Sjoergstatic	void	settdsym __P((type_t *, sym_t *));
6612099Sjoergstatic	tspec_t	mrgtspec __P((tspec_t, tspec_t));
6712099Sjoergstatic	void	align __P((int, int));
6812099Sjoergstatic	sym_t	*newtag __P((sym_t *, scl_t, int, int));
6912099Sjoergstatic	int	eqargs __P((type_t *, type_t *, int *));
7012099Sjoergstatic	int	mnoarg __P((type_t *, int *));
7112099Sjoergstatic	int	chkosdef __P((sym_t *, sym_t *));
7212099Sjoergstatic	int	chkptdecl __P((sym_t *, sym_t *));
7312099Sjoergstatic	sym_t	*nsfunc __P((sym_t *, sym_t *));
7412099Sjoergstatic	void	osfunc __P((sym_t *, sym_t *));
7512099Sjoergstatic	void	ledecl __P((sym_t *));
7612099Sjoergstatic	int	chkinit __P((sym_t *));
7712099Sjoergstatic	void	chkausg __P((int, sym_t *));
7812099Sjoergstatic	void	chkvusg __P((int, sym_t *));
7912099Sjoergstatic	void	chklusg __P((sym_t *));
8012099Sjoergstatic	void	chktusg __P((sym_t *));
8112099Sjoergstatic	void	chkglvar __P((sym_t *));
8212099Sjoergstatic	void	glchksz __P((sym_t *));
8312099Sjoerg
8412099Sjoerg/*
8512099Sjoerg * initializes all global vars used in declarations
8612099Sjoerg */
8712099Sjoergvoid
8812099Sjoerginitdecl()
8912099Sjoerg{
9012099Sjoerg	int	i;
9112099Sjoerg	static	struct {
9212099Sjoerg		tspec_t	it_tspec;
9312099Sjoerg		ttab_t	it_ttab;
9412099Sjoerg	} ittab[] = {
9512099Sjoerg		{ SIGNED,   { 0, 0,
9612099Sjoerg			      SIGNED, UNSIGN,
9712099Sjoerg			      0, 0, 0, 0, 0, "signed" } },
9812099Sjoerg		{ UNSIGN,   { 0, 0,
9912099Sjoerg			      SIGNED, UNSIGN,
10012099Sjoerg			      0, 0, 0, 0, 0, "unsigned" } },
10112099Sjoerg		{ CHAR,	    { CHAR_BIT, CHAR_BIT,
10212099Sjoerg			      SCHAR, UCHAR,
10312099Sjoerg			      1, 0, 0, 1, 1, "char" } },
10412099Sjoerg		{ SCHAR,    { CHAR_BIT, CHAR_BIT,
10512099Sjoerg			      SCHAR, UCHAR,
10612099Sjoerg			      1, 0, 0, 1, 1, "signed char" } },
10712099Sjoerg		{ UCHAR,    { CHAR_BIT, CHAR_BIT,
10812099Sjoerg			      SCHAR, UCHAR,
10912099Sjoerg			      1, 1, 0, 1, 1, "unsigned char" } },
11012099Sjoerg		{ SHORT,    { sizeof (short) * CHAR_BIT, 2 * CHAR_BIT,
11112099Sjoerg			      SHORT, USHORT,
11212099Sjoerg			      1, 0, 0, 1, 1, "short" } },
11312099Sjoerg		{ USHORT,   { sizeof (u_short) * CHAR_BIT, 2 * CHAR_BIT,
11412099Sjoerg			      SHORT, USHORT,
11512099Sjoerg			      1, 1, 0, 1, 1, "unsigned short" } },
11612099Sjoerg		{ INT,      { sizeof (int) * CHAR_BIT, 3 * CHAR_BIT,
11712099Sjoerg			      INT, UINT,
11812099Sjoerg			      1, 0, 0, 1, 1, "int" } },
11912099Sjoerg		{ UINT,     { sizeof (u_int) * CHAR_BIT, 3 * CHAR_BIT,
12012099Sjoerg			      INT, UINT,
12112099Sjoerg			      1, 1, 0, 1, 1, "unsigned int" } },
12212099Sjoerg		{ LONG,     { sizeof (long) * CHAR_BIT, 4 * CHAR_BIT,
12312099Sjoerg			      LONG, ULONG,
12412099Sjoerg			      1, 0, 0, 1, 1, "long" } },
12512099Sjoerg		{ ULONG,    { sizeof (u_long) * CHAR_BIT, 4 * CHAR_BIT,
12612099Sjoerg			      LONG, ULONG,
12712099Sjoerg			      1, 1, 0, 1, 1, "unsigned long" } },
12812099Sjoerg		{ QUAD,     { sizeof (quad_t) * CHAR_BIT, 8 * CHAR_BIT,
12912099Sjoerg			      QUAD, UQUAD,
13012099Sjoerg			      1, 0, 0, 1, 1, "long long" } },
13112099Sjoerg		{ UQUAD,    { sizeof (u_quad_t) * CHAR_BIT, 8 * CHAR_BIT,
13212099Sjoerg			      QUAD, UQUAD,
13312099Sjoerg			      1, 1, 0, 1, 1, "unsigned long long" } },
13412099Sjoerg		{ FLOAT,    { sizeof (float) * CHAR_BIT, 4 * CHAR_BIT,
13512099Sjoerg			      FLOAT, FLOAT,
13612099Sjoerg			      0, 0, 1, 1, 1, "float" } },
13712099Sjoerg		{ DOUBLE,   { sizeof (double) * CHAR_BIT, 8 * CHAR_BIT,
13812099Sjoerg			      DOUBLE, DOUBLE,
13912099Sjoerg			      0, 0, 1, 1, 1, "double" } },
14012099Sjoerg		{ LDOUBLE,  { sizeof (ldbl_t) * CHAR_BIT, 10 * CHAR_BIT,
14112099Sjoerg			      LDOUBLE, LDOUBLE,
14212099Sjoerg			      0, 0, 1, 1, 1, "long double" } },
14312099Sjoerg		{ VOID,     { -1, -1,
14412099Sjoerg			      VOID, VOID,
14512099Sjoerg			      0, 0, 0, 0, 0, "void" } },
14612099Sjoerg		{ STRUCT,   { -1, -1,
14712099Sjoerg			      STRUCT, STRUCT,
14812099Sjoerg			      0, 0, 0, 0, 0, "struct" } },
14912099Sjoerg		{ UNION,    { -1, -1,
15012099Sjoerg			      UNION, UNION,
15112099Sjoerg			      0, 0, 0, 0, 0, "union" } },
15212099Sjoerg		{ ENUM,     { sizeof (int) * CHAR_BIT, 3 * CHAR_BIT,
15312099Sjoerg			      ENUM, ENUM,
15412099Sjoerg			      1, 0, 0, 1, 1, "enum" } },
15512099Sjoerg		{ PTR,      { sizeof (void *) * CHAR_BIT, 4 * CHAR_BIT,
15612099Sjoerg			      PTR, PTR,
15712099Sjoerg			      0, 1, 0, 0, 1, "pointer" } },
15812099Sjoerg		{ ARRAY,    { -1, -1,
15912099Sjoerg			      ARRAY, ARRAY,
16012099Sjoerg			      0, 0, 0, 0, 0, "array" } },
16112099Sjoerg		{ FUNC,     { -1, -1,
16212099Sjoerg			      FUNC, FUNC,
16312099Sjoerg			      0, 0, 0, 0, 0, "function" } },
16412099Sjoerg	};
16512099Sjoerg
16612099Sjoerg	/* declaration stack */
16712099Sjoerg	dcs = xcalloc(1, sizeof (dinfo_t));
16812099Sjoerg	dcs->d_ctx = EXTERN;
16912099Sjoerg	dcs->d_ldlsym = &dcs->d_dlsyms;
17012099Sjoerg
17112099Sjoerg	/* type information and classification */
17212099Sjoerg	for (i = 0; i < sizeof (ittab) / sizeof (ittab[0]); i++)
17312099Sjoerg		STRUCT_ASSIGN(ttab[ittab[i].it_tspec], ittab[i].it_ttab);
17412099Sjoerg	if (!pflag) {
17512099Sjoerg		for (i = 0; i < NTSPEC; i++)
17612099Sjoerg			ttab[i].tt_psz = ttab[i].tt_sz;
17712099Sjoerg	}
17812099Sjoerg
17912099Sjoerg	/* shared type structures */
18012099Sjoerg	typetab = xcalloc(NTSPEC, sizeof (type_t));
18112099Sjoerg	for (i = 0; i < NTSPEC; i++)
18212099Sjoerg		typetab[i].t_tspec = NOTSPEC;
18312099Sjoerg	typetab[CHAR].t_tspec = CHAR;
18412099Sjoerg	typetab[SCHAR].t_tspec = SCHAR;
18512099Sjoerg	typetab[UCHAR].t_tspec = UCHAR;
18612099Sjoerg	typetab[SHORT].t_tspec = SHORT;
18712099Sjoerg	typetab[USHORT].t_tspec = USHORT;
18812099Sjoerg	typetab[INT].t_tspec = INT;
18912099Sjoerg	typetab[UINT].t_tspec = UINT;
19012099Sjoerg	typetab[LONG].t_tspec = LONG;
19112099Sjoerg	typetab[ULONG].t_tspec = ULONG;
19212099Sjoerg	typetab[QUAD].t_tspec = QUAD;
19312099Sjoerg	typetab[UQUAD].t_tspec = UQUAD;
19412099Sjoerg	typetab[FLOAT].t_tspec = FLOAT;
19512099Sjoerg	typetab[DOUBLE].t_tspec = DOUBLE;
19612099Sjoerg	typetab[LDOUBLE].t_tspec = LDOUBLE;
19712099Sjoerg	typetab[VOID].t_tspec = VOID;
19812099Sjoerg	/*
19912099Sjoerg	 * Next two are not real types. They are only used by the parser
20012099Sjoerg	 * to return keywords "signed" and "unsigned"
20112099Sjoerg	 */
20212099Sjoerg	typetab[SIGNED].t_tspec = SIGNED;
20312099Sjoerg	typetab[UNSIGN].t_tspec = UNSIGN;
20412099Sjoerg}
20512099Sjoerg
20612099Sjoerg/*
20712099Sjoerg * Returns a shared type structure vor arithmetic types and void.
20812099Sjoerg *
20912099Sjoerg * It's important do duplicate this structure (using duptyp() or tdupdyp())
21012099Sjoerg * if it is to be modified (adding qualifiers or anything else).
21112099Sjoerg */
21212099Sjoergtype_t *
21312099Sjoerggettyp(t)
21412099Sjoerg	tspec_t	t;
21512099Sjoerg{
21612099Sjoerg	return (&typetab[t]);
21712099Sjoerg}
21812099Sjoerg
21912099Sjoergtype_t *
22012099Sjoergduptyp(tp)
22112099Sjoerg	const	type_t *tp;
22212099Sjoerg{
22312099Sjoerg	type_t	*ntp;
22412099Sjoerg
22512099Sjoerg	ntp = getblk(sizeof (type_t));
22612099Sjoerg	STRUCT_ASSIGN(*ntp, *tp);
22712099Sjoerg	return (ntp);
22812099Sjoerg}
22912099Sjoerg
23012099Sjoerg/*
23112099Sjoerg * Use tduptyp() instead of duptyp() inside expressions (if the
23212099Sjoerg * allocated memory should be freed after the expr).
23312099Sjoerg */
23412099Sjoergtype_t *
23512099Sjoergtduptyp(tp)
23612099Sjoerg	const	type_t *tp;
23712099Sjoerg{
23812099Sjoerg	type_t	*ntp;
23912099Sjoerg
24012099Sjoerg	ntp = tgetblk(sizeof (type_t));
24112099Sjoerg	STRUCT_ASSIGN(*ntp, *tp);
24212099Sjoerg	return (ntp);
24312099Sjoerg}
24412099Sjoerg
24512099Sjoerg/*
24612099Sjoerg * Returns 1 if the argument is void or an incomplete array,
24712099Sjoerg * struct, union or enum type.
24812099Sjoerg */
24912099Sjoergint
25012099Sjoergincompl(tp)
25112099Sjoerg	type_t	*tp;
25212099Sjoerg{
25312099Sjoerg	tspec_t	t;
25412099Sjoerg
25512099Sjoerg	if ((t = tp->t_tspec) == VOID) {
25612099Sjoerg		return (1);
25712099Sjoerg	} else if (t == ARRAY) {
25812099Sjoerg		return (tp->t_aincompl);
25912099Sjoerg	} else if (t == STRUCT || t == UNION) {
26012099Sjoerg		return (tp->t_str->sincompl);
26112099Sjoerg	} else if (t == ENUM) {
26212099Sjoerg		return (tp->t_enum->eincompl);
26312099Sjoerg	}
26412099Sjoerg	return (0);
26512099Sjoerg}
26612099Sjoerg
26712099Sjoerg/*
26812099Sjoerg * Set the flag for (in)complete array, struct, union or enum
26912099Sjoerg * types.
27012099Sjoerg */
27112099Sjoergvoid
27212099Sjoergsetcompl(tp, ic)
27312099Sjoerg	type_t	*tp;
27412099Sjoerg	int	ic;
27512099Sjoerg{
27612099Sjoerg	tspec_t	t;
27712099Sjoerg
27812099Sjoerg	if ((t = tp->t_tspec) == ARRAY) {
27912099Sjoerg		tp->t_aincompl = ic;
28012099Sjoerg	} else if (t == STRUCT || t == UNION) {
28112099Sjoerg		tp->t_str->sincompl = ic;
28212099Sjoerg	} else {
28312099Sjoerg		if (t != ENUM)
28412099Sjoerg			lerror("setcompl() 1");
28512099Sjoerg		tp->t_enum->eincompl = ic;
28612099Sjoerg	}
28712099Sjoerg}
28812099Sjoerg
28912099Sjoerg/*
29012099Sjoerg * Remember the storage class of the current declaration in dcs->d_scl
29112099Sjoerg * (the top element of the declaration stack) and detect multiple
29212099Sjoerg * storage classes.
29312099Sjoerg */
29412099Sjoergvoid
29512099Sjoergaddscl(sc)
29612099Sjoerg	scl_t	sc;
29712099Sjoerg{
29812099Sjoerg	if (sc == INLINE) {
29912099Sjoerg		if (dcs->d_inline)
30012099Sjoerg			/* duplicate '%s' */
30112099Sjoerg			warning(10, "inline");
30212099Sjoerg		dcs->d_inline = 1;
30312099Sjoerg		return;
30412099Sjoerg	}
30512099Sjoerg	if (dcs->d_type != NULL || dcs->d_atyp != NOTSPEC ||
30612099Sjoerg	    dcs->d_smod != NOTSPEC || dcs->d_lmod != NOTSPEC) {
30712099Sjoerg		/* storage class after type is obsolescent */
30812099Sjoerg		warning(83);
30912099Sjoerg	}
31012099Sjoerg	if (dcs->d_scl == NOSCL) {
31112099Sjoerg		dcs->d_scl = sc;
31212099Sjoerg	} else {
31312099Sjoerg		/*
31412099Sjoerg		 * multiple storage classes. An error will be reported in
31512099Sjoerg		 * deftyp().
31612099Sjoerg		 */
31712099Sjoerg		dcs->d_mscl = 1;
31812099Sjoerg	}
31912099Sjoerg}
32012099Sjoerg
32112099Sjoerg/*
32212099Sjoerg * Remember the type, modifier or typedef name returned by the parser
32312099Sjoerg * in *dcs (top element of decl stack). This information is used in
32412099Sjoerg * deftyp() to build the type used for all declarators in this
32512099Sjoerg * declaration.
32612099Sjoerg *
32712099Sjoerg * Is tp->t_typedef 1, the type comes from a previously defined typename.
32812099Sjoerg * Otherwise it comes from a type specifier (int, long, ...) or a
32912099Sjoerg * struct/union/enum tag.
33012099Sjoerg */
33112099Sjoergvoid
33212099Sjoergaddtype(tp)
33312099Sjoerg	type_t	*tp;
33412099Sjoerg{
33512099Sjoerg	tspec_t	t;
33612099Sjoerg
33712099Sjoerg	if (tp->t_typedef) {
33812099Sjoerg		if (dcs->d_type != NULL || dcs->d_atyp != NOTSPEC ||
33912099Sjoerg		    dcs->d_lmod != NOTSPEC || dcs->d_smod != NOTSPEC) {
34012099Sjoerg			/*
34112099Sjoerg			 * something like "typedef int a; int a b;"
34212099Sjoerg			 * This should not happen with current grammar.
34312099Sjoerg			 */
34412099Sjoerg			lerror("addtype()");
34512099Sjoerg		}
34612099Sjoerg		dcs->d_type = tp;
34712099Sjoerg		return;
34812099Sjoerg	}
34912099Sjoerg
35012099Sjoerg	t = tp->t_tspec;
35112099Sjoerg
35212099Sjoerg	if (t == STRUCT || t == UNION || t == ENUM) {
35312099Sjoerg		/*
35412099Sjoerg		 * something like "int struct a ..."
35512099Sjoerg		 * struct/union/enum with anything else is not allowed
35612099Sjoerg		 */
35712099Sjoerg		if (dcs->d_type != NULL || dcs->d_atyp != NOTSPEC ||
35812099Sjoerg		    dcs->d_lmod != NOTSPEC || dcs->d_smod != NOTSPEC) {
35912099Sjoerg			/*
36012099Sjoerg			 * remember that an error must be reported in
36112099Sjoerg			 * deftyp().
36212099Sjoerg			 */
36312099Sjoerg			dcs->d_terr = 1;
36412099Sjoerg			dcs->d_atyp = dcs->d_lmod = dcs->d_smod = NOTSPEC;
36512099Sjoerg		}
36612099Sjoerg		dcs->d_type = tp;
36712099Sjoerg		return;
36812099Sjoerg	}
36912099Sjoerg
37012099Sjoerg	if (dcs->d_type != NULL && !dcs->d_type->t_typedef) {
37112099Sjoerg		/*
37212099Sjoerg		 * something like "struct a int"
37312099Sjoerg		 * struct/union/enum with anything else is not allowed
37412099Sjoerg		 */
37512099Sjoerg		dcs->d_terr = 1;
37612099Sjoerg		return;
37712099Sjoerg	}
37812099Sjoerg
37912099Sjoerg	if (t == LONG && dcs->d_lmod == LONG) {
38012099Sjoerg		/* "long long" or "long ... long" */
38112099Sjoerg		t = QUAD;
38212099Sjoerg		dcs->d_lmod = NOTSPEC;
38312099Sjoerg		if (!quadflg)
38412099Sjoerg			/* %s C does not support 'long long' */
38512099Sjoerg			(void)gnuism(265, tflag ? "traditional" : "ANSI");
38612099Sjoerg	}
38712099Sjoerg
38812099Sjoerg	if (dcs->d_type != NULL && dcs->d_type->t_typedef) {
38912099Sjoerg		/* something like "typedef int a; a long ..." */
39012099Sjoerg		dcs->d_type = tdeferr(dcs->d_type, t);
39112099Sjoerg		return;
39212099Sjoerg	}
39312099Sjoerg
39412099Sjoerg	/* now it can be only a combination of arithmetic types and void */
39512099Sjoerg	if (t == SIGNED || t == UNSIGN) {
39612099Sjoerg		/* remeber specifiers "signed" and "unsigned" in dcs->d_smod */
39712099Sjoerg		if (dcs->d_smod != NOTSPEC)
39812099Sjoerg			/*
39912099Sjoerg			 * more then one "signed" and/or "unsigned"; print
40012099Sjoerg			 * an error in deftyp()
40112099Sjoerg			 */
40212099Sjoerg			dcs->d_terr = 1;
40312099Sjoerg		dcs->d_smod = t;
40412099Sjoerg	} else if (t == SHORT || t == LONG || t == QUAD) {
40512099Sjoerg		/*
40612099Sjoerg		 * remember specifiers "short", "long" and "long long" in
40712099Sjoerg		 * dcs->d_lmod
40812099Sjoerg		 */
40912099Sjoerg		if (dcs->d_lmod != NOTSPEC)
41012099Sjoerg			/* more than one, print error in deftyp() */
41112099Sjoerg			dcs->d_terr = 1;
41212099Sjoerg		dcs->d_lmod = t;
41312099Sjoerg	} else {
41412099Sjoerg		/*
41512099Sjoerg		 * remember specifiers "void", "char", "int", "float" or
41612099Sjoerg		 * "double" int dcs->d_atyp
41712099Sjoerg		 */
41812099Sjoerg		if (dcs->d_atyp != NOTSPEC)
41912099Sjoerg			/* more than one, print error in deftyp() */
42012099Sjoerg			dcs->d_terr = 1;
42112099Sjoerg		dcs->d_atyp = t;
42212099Sjoerg	}
42312099Sjoerg}
42412099Sjoerg
42512099Sjoerg/*
42612099Sjoerg * called if a list of declaration specifiers contains a typedef name
42712099Sjoerg * and other specifiers (except struct, union, enum, typedef name)
42812099Sjoerg */
42912099Sjoergstatic type_t *
43012099Sjoergtdeferr(td, t)
43112099Sjoerg	type_t	*td;
43212099Sjoerg	tspec_t	t;
43312099Sjoerg{
43412099Sjoerg	tspec_t	t2;
43512099Sjoerg
43612099Sjoerg	t2 = td->t_tspec;
43712099Sjoerg
43812099Sjoerg	switch (t) {
43912099Sjoerg	case SIGNED:
44012099Sjoerg	case UNSIGN:
44112099Sjoerg		if (t2 == CHAR || t2 == SHORT || t2 == INT || t2 == LONG ||
44212099Sjoerg		    t2 == QUAD) {
44312099Sjoerg			if (!tflag)
44412099Sjoerg				/* modifying typedef with ... */
44512099Sjoerg				warning(5, ttab[t].tt_name);
44612099Sjoerg			td = duptyp(gettyp(mrgtspec(t2, t)));
44712099Sjoerg			td->t_typedef = 1;
44812099Sjoerg			return (td);
44912099Sjoerg		}
45012099Sjoerg		break;
45112099Sjoerg	case SHORT:
45212099Sjoerg		if (t2 == INT || t2 == UINT) {
45312099Sjoerg			/* modifying typedef with ... */
45412099Sjoerg			warning(5, "short");
45512099Sjoerg			td = duptyp(gettyp(t2 == INT ? SHORT : USHORT));
45612099Sjoerg			td->t_typedef = 1;
45712099Sjoerg			return (td);
45812099Sjoerg		}
45912099Sjoerg		break;
46012099Sjoerg	case LONG:
46112099Sjoerg		if (t2 == INT || t2 == UINT || t2 == LONG || t2 == ULONG ||
46212099Sjoerg		    t2 == FLOAT || t2 == DOUBLE) {
46312099Sjoerg			/* modifying typedef with ... */
46412099Sjoerg			warning(5, "long");
46512099Sjoerg			if (t2 == INT) {
46612099Sjoerg				td = gettyp(LONG);
46712099Sjoerg			} else if (t2 == UINT) {
46812099Sjoerg				td = gettyp(ULONG);
46912099Sjoerg			} else if (t2 == LONG) {
47012099Sjoerg				td = gettyp(QUAD);
47112099Sjoerg			} else if (t2 == ULONG) {
47212099Sjoerg				td = gettyp(UQUAD);
47312099Sjoerg			} else if (t2 == FLOAT) {
47412099Sjoerg				td = gettyp(DOUBLE);
47512099Sjoerg			} else if (t2 == DOUBLE) {
47612099Sjoerg				td = gettyp(LDOUBLE);
47712099Sjoerg			}
47812099Sjoerg			td = duptyp(td);
47912099Sjoerg			td->t_typedef = 1;
48012099Sjoerg			return (td);
48112099Sjoerg		}
48212099Sjoerg		break;
48312099Sjoerg		/* LINTED (enumeration values not handled in switch) */
48417142Sjkh	default:
48512099Sjoerg	}
48612099Sjoerg
48712099Sjoerg	/* Anything other is not accepted. */
48812099Sjoerg
48912099Sjoerg	dcs->d_terr = 1;
49012099Sjoerg	return (td);
49112099Sjoerg}
49212099Sjoerg
49312099Sjoerg/*
49412099Sjoerg * Remember the symbol of a typedef name (2nd arg) in a struct, union
49512099Sjoerg * or enum tag if the typedef name is the first defined for this tag.
49612099Sjoerg *
49712099Sjoerg * If the tag is unnamed, the typdef name is used for identification
49812099Sjoerg * of this tag in lint2. Although its possible that more then one typedef
49912099Sjoerg * name is defined for one tag, the first name defined should be unique
50012099Sjoerg * if the tag is unnamed.
50112099Sjoerg */
50212099Sjoergstatic void
50312099Sjoergsettdsym(tp, sym)
50412099Sjoerg	type_t	*tp;
50512099Sjoerg	sym_t	*sym;
50612099Sjoerg{
50712099Sjoerg	tspec_t	t;
50812099Sjoerg
50912099Sjoerg	if ((t = tp->t_tspec) == STRUCT || t == UNION) {
51012099Sjoerg		if (tp->t_str->stdef == NULL)
51112099Sjoerg			tp->t_str->stdef = sym;
51212099Sjoerg	} else if (t == ENUM) {
51312099Sjoerg		if (tp->t_enum->etdef == NULL)
51412099Sjoerg			tp->t_enum->etdef = sym;
51512099Sjoerg	}
51612099Sjoerg}
51712099Sjoerg
51812099Sjoerg/*
51912099Sjoerg * Remember a qualifier which is part of the declaration specifiers
52012099Sjoerg * (and not the declarator) in the top element of the declaration stack.
52112099Sjoerg * Also detect multiple qualifiers of the same kind.
52212099Sjoerg
52312099Sjoerg * The rememberd qualifier is used by deftyp() to construct the type
52412099Sjoerg * for all declarators.
52512099Sjoerg */
52612099Sjoergvoid
52712099Sjoergaddqual(q)
52812099Sjoerg	tqual_t	q;
52912099Sjoerg{
53012099Sjoerg	if (q == CONST) {
53112099Sjoerg		if (dcs->d_const) {
53212099Sjoerg			/* duplicate "%s" */
53312099Sjoerg			warning(10, "const");
53412099Sjoerg		}
53512099Sjoerg		dcs->d_const = 1;
53612099Sjoerg	} else {
53712099Sjoerg		if (q != VOLATILE)
53812099Sjoerg			lerror("addqual() 1");
53912099Sjoerg		if (dcs->d_volatile) {
54012099Sjoerg			/* duplicate "%s" */
54112099Sjoerg			warning(10, "volatile");
54212099Sjoerg		}
54312099Sjoerg		dcs->d_volatile = 1;
54412099Sjoerg	}
54512099Sjoerg}
54612099Sjoerg
54712099Sjoerg/*
54812099Sjoerg * Go to the next declaration level (structs, nested structs, blocks,
54912099Sjoerg * argument declaration lists ...)
55012099Sjoerg */
55112099Sjoergvoid
55212099Sjoergpushdecl(sc)
55312099Sjoerg	scl_t	sc;
55412099Sjoerg{
55512099Sjoerg	dinfo_t	*di;
55612099Sjoerg
55712099Sjoerg	if (dflag)
55812099Sjoerg		(void)printf("pushdecl(%d)\n", (int)sc);
55912099Sjoerg
56012099Sjoerg	/* put a new element on the declaration stack */
56112099Sjoerg	di = xcalloc(1, sizeof (dinfo_t));
56212099Sjoerg	di->d_nxt = dcs;
56312099Sjoerg	dcs = di;
56412099Sjoerg	di->d_ctx = sc;
56512099Sjoerg	di->d_ldlsym = &di->d_dlsyms;
56612099Sjoerg}
56712099Sjoerg
56812099Sjoerg/*
56912099Sjoerg * Go back to previous declaration level
57012099Sjoerg */
57112099Sjoergvoid
57212099Sjoergpopdecl()
57312099Sjoerg{
57412099Sjoerg	dinfo_t	*di;
57512099Sjoerg
57612099Sjoerg	if (dflag)
57712099Sjoerg		(void)printf("popdecl(%d)\n", (int)dcs->d_ctx);
57812099Sjoerg
57912099Sjoerg	if (dcs->d_nxt == NULL)
58012099Sjoerg		lerror("popdecl() 1");
58112099Sjoerg	di = dcs;
58212099Sjoerg	dcs = di->d_nxt;
58312099Sjoerg	switch (di->d_ctx) {
58412099Sjoerg	case EXTERN:
58512099Sjoerg		/* there is nothing after external declarations */
58612099Sjoerg		lerror("popdecl() 2");
58712099Sjoerg		/* NOTREACHED */
58812099Sjoerg	case MOS:
58912099Sjoerg	case MOU:
59012099Sjoerg	case ENUMCON:
59112099Sjoerg		/*
59212099Sjoerg		 * Symbols declared in (nested) structs or enums are
59312099Sjoerg		 * part of the next level (they are removed from the
59412099Sjoerg		 * symbol table if the symbols of the outher level are
59512099Sjoerg		 * removed)
59612099Sjoerg		 */
59712099Sjoerg		if ((*dcs->d_ldlsym = di->d_dlsyms) != NULL)
59812099Sjoerg			dcs->d_ldlsym = di->d_ldlsym;
59912099Sjoerg		break;
60012099Sjoerg	case ARG:
60112099Sjoerg		/*
60212099Sjoerg		 * All symbols in dcs->d_dlsyms are introduced in old style
60312099Sjoerg		 * argument declarations (it's not clean, but possible).
60412099Sjoerg		 * They are appended to the list of symbols declared in
60512099Sjoerg		 * an old style argument identifier list or a new style
60612099Sjoerg		 * parameter type list.
60712099Sjoerg		 */
60812099Sjoerg		if (di->d_dlsyms != NULL) {
60912099Sjoerg			*di->d_ldlsym = dcs->d_fpsyms;
61012099Sjoerg			dcs->d_fpsyms = di->d_dlsyms;
61112099Sjoerg		}
61212099Sjoerg		break;
61312099Sjoerg	case ABSTRACT:
61412099Sjoerg		/*
61512099Sjoerg		 * casts and sizeof
61612099Sjoerg		 * Append all symbols declared in the abstract declaration
61712099Sjoerg		 * to the list of symbols declared in the surounding decl.
61812099Sjoerg		 * or block.
61912099Sjoerg		 * XXX I'm not sure whether they should be removed from the
62012099Sjoerg		 * symbol table now or later.
62112099Sjoerg		 */
62212099Sjoerg		if ((*dcs->d_ldlsym = di->d_dlsyms) != NULL)
62312099Sjoerg			dcs->d_ldlsym = di->d_ldlsym;
62412099Sjoerg		break;
62512099Sjoerg	case AUTO:
62612099Sjoerg		/* check usage of local vars */
62712099Sjoerg		chkusage(di);
62812099Sjoerg		/* FALLTHROUGH */
62912099Sjoerg	case PARG:
63012099Sjoerg		/* usage of arguments will be checked by funcend() */
63112099Sjoerg		rmsyms(di->d_dlsyms);
63212099Sjoerg		break;
63312099Sjoerg	default:
63412099Sjoerg		lerror("popdecl() 3");
63512099Sjoerg	}
63612099Sjoerg	free(di);
63712099Sjoerg}
63812099Sjoerg
63912099Sjoerg/*
64012099Sjoerg * Set flag d_asm in all declaration stack elements up to the
64112099Sjoerg * outermost one.
64212099Sjoerg *
64312099Sjoerg * This is used to mark compound statements which have, possibly in
64412099Sjoerg * nested compound statements, asm statements. For these compound
64512099Sjoerg * statements no warnings about unused or unitialized variables are
64612099Sjoerg * printed.
64712099Sjoerg *
64812099Sjoerg * There is no need to clear d_asm in dinfo structs with context AUTO,
64912099Sjoerg * because these structs are freed at the end of the compound statement.
65012099Sjoerg * But it must be cleard in the outermost dinfo struct, which has
65112099Sjoerg * context EXTERN. This could be done in clrtyp() and would work for
65212099Sjoerg * C, but not for C++ (due to mixed statements and declarations). Thus
65312099Sjoerg * we clear it in glclup(), which is used to do some cleanup after
65412099Sjoerg * global declarations/definitions.
65512099Sjoerg */
65612099Sjoergvoid
65712099Sjoergsetasm()
65812099Sjoerg{
65912099Sjoerg	dinfo_t	*di;
66012099Sjoerg
66112099Sjoerg	for (di = dcs; di != NULL; di = di->d_nxt)
66212099Sjoerg		di->d_asm = 1;
66312099Sjoerg}
66412099Sjoerg
66512099Sjoerg/*
66612099Sjoerg * Clean all elements of the top element of declaration stack which
66712099Sjoerg * will be used by the next declaration
66812099Sjoerg */
66912099Sjoergvoid
67012099Sjoergclrtyp()
67112099Sjoerg{
67212099Sjoerg	dcs->d_atyp = dcs->d_smod = dcs->d_lmod = NOTSPEC;
67312099Sjoerg	dcs->d_scl = NOSCL;
67412099Sjoerg	dcs->d_type = NULL;
67512099Sjoerg	dcs->d_const = dcs->d_volatile = 0;
67612099Sjoerg	dcs->d_inline = 0;
67712099Sjoerg	dcs->d_mscl = dcs->d_terr = 0;
67812099Sjoerg	dcs->d_nedecl = 0;
67912099Sjoerg	dcs->d_notyp = 0;
68012099Sjoerg}
68112099Sjoerg
68212099Sjoerg/*
68312099Sjoerg * Create a type structure from the informations gathered in
68412099Sjoerg * the declaration stack.
68512099Sjoerg * Complain about storage classes which are not possible in current
68612099Sjoerg * context.
68712099Sjoerg */
68812099Sjoergvoid
68912099Sjoergdeftyp()
69012099Sjoerg{
69112099Sjoerg	tspec_t	t, s, l;
69212099Sjoerg	type_t	*tp;
69312099Sjoerg	scl_t	scl;
69412099Sjoerg
69512099Sjoerg	t = dcs->d_atyp;		/* CHAR, INT, FLOAT, DOUBLE, VOID */
69612099Sjoerg	s = dcs->d_smod;		/* SIGNED, UNSIGNED */
69712099Sjoerg	l = dcs->d_lmod;		/* SHORT, LONG, QUAD */
69812099Sjoerg	tp = dcs->d_type;
69912099Sjoerg	scl = dcs->d_scl;
70012099Sjoerg
70112099Sjoerg	if (t == NOTSPEC && s == NOTSPEC && l == NOTSPEC && tp == NULL)
70212099Sjoerg		dcs->d_notyp = 1;
70312099Sjoerg
70412099Sjoerg	if (tp != NULL && (t != NOTSPEC || s != NOTSPEC || l != NOTSPEC)) {
70512099Sjoerg		/* should never happen */
70612099Sjoerg		lerror("deftyp() 1");
70712099Sjoerg	}
70812099Sjoerg
70912099Sjoerg	if (tp == NULL) {
71012099Sjoerg		switch (t) {
71112099Sjoerg		case NOTSPEC:
71212099Sjoerg			t = INT;
71312099Sjoerg			/* FALLTHROUGH */
71412099Sjoerg		case INT:
71512099Sjoerg			if (s == NOTSPEC)
71612099Sjoerg				s = SIGNED;
71712099Sjoerg			break;
71812099Sjoerg		case CHAR:
71912099Sjoerg			if (l != NOTSPEC) {
72012099Sjoerg				dcs->d_terr = 1;
72112099Sjoerg				l = NOTSPEC;
72212099Sjoerg			}
72312099Sjoerg			break;
72412099Sjoerg		case FLOAT:
72512099Sjoerg			if (l == LONG) {
72612099Sjoerg				l = NOTSPEC;
72712099Sjoerg				t = DOUBLE;
72812099Sjoerg				if (!tflag)
72912099Sjoerg					/* use 'double' instead of ...  */
73012099Sjoerg					warning(6);
73112099Sjoerg			}
73212099Sjoerg			break;
73312099Sjoerg		case DOUBLE:
73412099Sjoerg			if (l == LONG) {
73512099Sjoerg				l = NOTSPEC;
73612099Sjoerg				t = LDOUBLE;
73712099Sjoerg				if (tflag)
73812099Sjoerg					/* 'long double' is illegal in ... */
73912099Sjoerg					warning(266);
74012099Sjoerg			}
74112099Sjoerg			break;
74212099Sjoerg		case VOID:
74312099Sjoerg			break;
74412099Sjoerg		default:
74512099Sjoerg			lerror("deftyp() 2");
74612099Sjoerg		}
74712099Sjoerg		if (t != INT && t != CHAR && (s != NOTSPEC || l != NOTSPEC)) {
74812099Sjoerg			dcs->d_terr = 1;
74912099Sjoerg			l = s = NOTSPEC;
75012099Sjoerg		}
75112099Sjoerg		if (l != NOTSPEC)
75212099Sjoerg			t = l;
75312099Sjoerg		dcs->d_type = gettyp(mrgtspec(t, s));
75412099Sjoerg	}
75512099Sjoerg
75612099Sjoerg	if (dcs->d_mscl) {
75712099Sjoerg		/* only one storage class allowed */
75812099Sjoerg		error(7);
75912099Sjoerg	}
76012099Sjoerg	if (dcs->d_terr) {
76112099Sjoerg		/* illegal type combination */
76212099Sjoerg		error(4);
76312099Sjoerg	}
76412099Sjoerg
76512099Sjoerg	if (dcs->d_ctx == EXTERN) {
76612099Sjoerg		if (scl == REG || scl == AUTO) {
76712099Sjoerg			/* illegal storage class */
76812099Sjoerg			error(8);
76912099Sjoerg			scl = NOSCL;
77012099Sjoerg		}
77112099Sjoerg	} else if (dcs->d_ctx == ARG || dcs->d_ctx == PARG) {
77212099Sjoerg		if (scl != NOSCL && scl != REG) {
77312099Sjoerg			/* only "register" valid ... */
77412099Sjoerg			error(9);
77512099Sjoerg			scl = NOSCL;
77612099Sjoerg		}
77712099Sjoerg	}
77812099Sjoerg
77912099Sjoerg	dcs->d_scl = scl;
78012099Sjoerg
78112099Sjoerg	if (dcs->d_const && dcs->d_type->t_const) {
78212099Sjoerg		if (!dcs->d_type->t_typedef)
78312099Sjoerg			lerror("deftyp() 3");
78412099Sjoerg		/* typedef already qualified with "%s" */
78512099Sjoerg		warning(68, "const");
78612099Sjoerg	}
78712099Sjoerg	if (dcs->d_volatile && dcs->d_type->t_volatile) {
78812099Sjoerg		if (!dcs->d_type->t_typedef)
78912099Sjoerg			lerror("deftyp() 4");
79012099Sjoerg		/* typedef already qualified with "%s" */
79112099Sjoerg		warning(68, "volatile");
79212099Sjoerg	}
79312099Sjoerg
79412099Sjoerg	if (dcs->d_const || dcs->d_volatile) {
79512099Sjoerg		dcs->d_type = duptyp(dcs->d_type);
79612099Sjoerg		dcs->d_type->t_const |= dcs->d_const;
79712099Sjoerg		dcs->d_type->t_volatile |= dcs->d_volatile;
79812099Sjoerg	}
79912099Sjoerg}
80012099Sjoerg
80112099Sjoerg/*
80212099Sjoerg * Merge type specifiers (char, ..., long long, signed, unsigned).
80312099Sjoerg */
80412099Sjoergstatic tspec_t
80512099Sjoergmrgtspec(t, s)
80612099Sjoerg	tspec_t	t, s;
80712099Sjoerg{
80812099Sjoerg	if (s == SIGNED || s == UNSIGN) {
80912099Sjoerg		if (t == CHAR) {
81012099Sjoerg			t = s == SIGNED ? SCHAR : UCHAR;
81112099Sjoerg		} else if (t == SHORT) {
81212099Sjoerg			t = s == SIGNED ? SHORT : USHORT;
81312099Sjoerg		} else if (t == INT) {
81412099Sjoerg			t = s == SIGNED ? INT : UINT;
81512099Sjoerg		} else if (t == LONG) {
81612099Sjoerg			t = s == SIGNED ? LONG : ULONG;
81712099Sjoerg		} else if (t == QUAD) {
81812099Sjoerg			t = s == SIGNED ? QUAD : UQUAD;
81912099Sjoerg		}
82012099Sjoerg	}
82112099Sjoerg
82212099Sjoerg	return (t);
82312099Sjoerg}
82412099Sjoerg
82512099Sjoerg/*
82612099Sjoerg * Return the length of a type in bit.
82712099Sjoerg *
82812099Sjoerg * Printing a message if the outhermost dimension of an array is 0 must
82912099Sjoerg * be done by the caller. All other problems are reported by length()
83012099Sjoerg * if name is not NULL.
83112099Sjoerg */
83212099Sjoergint
83312099Sjoerglength(tp, name)
83412099Sjoerg	type_t	*tp;
83512099Sjoerg	const	char *name;
83612099Sjoerg{
83712099Sjoerg	int	elem, elsz;
83812099Sjoerg
83912099Sjoerg	elem = 1;
84012099Sjoerg	while (tp->t_tspec == ARRAY) {
84112099Sjoerg		elem *= tp->t_dim;
84212099Sjoerg		tp = tp->t_subt;
84312099Sjoerg	}
84412099Sjoerg	switch (tp->t_tspec) {
84512099Sjoerg	case FUNC:
84612099Sjoerg		/* compiler takes size of function */
84712099Sjoerg		lerror(msgs[12]);
84812099Sjoerg		/* NOTREACHED */
84912099Sjoerg	case STRUCT:
85012099Sjoerg	case UNION:
85112099Sjoerg		if (incompl(tp) && name != NULL) {
85212099Sjoerg			/* incomplete structure or union %s: %s */
85312099Sjoerg			error(31, tp->t_str->stag->s_name, name);
85412099Sjoerg		}
85512099Sjoerg		elsz = tp->t_str->size;
85612099Sjoerg		break;
85712099Sjoerg	case ENUM:
85812099Sjoerg		if (incompl(tp) && name != NULL) {
85912099Sjoerg			/* incomplete enum type: %s */
86012099Sjoerg			warning(13, name);
86112099Sjoerg		}
86212099Sjoerg		/* FALLTHROUGH */
86312099Sjoerg	default:
86412099Sjoerg		elsz = size(tp->t_tspec);
86512099Sjoerg		if (elsz <= 0)
86612099Sjoerg			lerror("length()");
86712099Sjoerg		break;
86812099Sjoerg	}
86912099Sjoerg	return (elem * elsz);
87012099Sjoerg}
87112099Sjoerg
87212099Sjoerg/*
87312099Sjoerg * Get the alignment of the given Type in bits.
87412099Sjoerg */
87512099Sjoergint
87612099Sjoerggetbound(tp)
87712099Sjoerg	type_t	*tp;
87812099Sjoerg{
87912099Sjoerg	int	a;
88012099Sjoerg	tspec_t	t;
88112099Sjoerg
88212099Sjoerg	while (tp->t_tspec == ARRAY)
88312099Sjoerg		tp = tp->t_subt;
88412099Sjoerg
88512099Sjoerg	if ((t = tp->t_tspec) == STRUCT || t == UNION) {
88612099Sjoerg		a = tp->t_str->align;
88712099Sjoerg	} else if (t == FUNC) {
88812099Sjoerg		/* compiler takes alignment of function */
88912099Sjoerg		error(14);
89012099Sjoerg		a = ALIGN(1) * CHAR_BIT;
89112099Sjoerg	} else {
89212099Sjoerg		if ((a = size(t)) == 0) {
89312099Sjoerg			a = CHAR_BIT;
89412099Sjoerg		} else if (a > ALIGN(1) * CHAR_BIT) {
89512099Sjoerg			a = ALIGN(1) * CHAR_BIT;
89612099Sjoerg		}
89712099Sjoerg	}
89812099Sjoerg	if (a < CHAR_BIT || a > ALIGN(1) * CHAR_BIT)
89912099Sjoerg		lerror("getbound() 1");
90012099Sjoerg	return (a);
90112099Sjoerg}
90212099Sjoerg
90312099Sjoerg/*
90412099Sjoerg * Concatenate two lists of symbols by s_nxt. Used by declarations of
90512099Sjoerg * struct/union/enum elements and parameters.
90612099Sjoerg */
90712099Sjoergsym_t *
90812099Sjoerglnklst(l1, l2)
90912099Sjoerg	sym_t	*l1, *l2;
91012099Sjoerg{
91112099Sjoerg	sym_t	*l;
91212099Sjoerg
91312099Sjoerg	if ((l = l1) == NULL)
91412099Sjoerg		return (l2);
91512099Sjoerg	while (l1->s_nxt != NULL)
91612099Sjoerg		l1 = l1->s_nxt;
91712099Sjoerg	l1->s_nxt = l2;
91812099Sjoerg	return (l);
91912099Sjoerg}
92012099Sjoerg
92112099Sjoerg/*
92212099Sjoerg * Check if the type of the given symbol is valid and print an error
92312099Sjoerg * message if it is not.
92412099Sjoerg *
92512099Sjoerg * Invalid types are:
92612099Sjoerg * - arrays of incomlete types or functions
92712099Sjoerg * - functions returning arrays or functions
92812099Sjoerg * - void types other than type of function or pointer
92912099Sjoerg */
93012099Sjoergvoid
93112099Sjoergchktyp(sym)
93212099Sjoerg	sym_t	*sym;
93312099Sjoerg{
93412099Sjoerg	tspec_t	to, t;
93512099Sjoerg	type_t	**tpp, *tp;
93612099Sjoerg
93712099Sjoerg	tpp = &sym->s_type;
93812099Sjoerg	to = NOTSPEC;
93912099Sjoerg	while ((tp = *tpp) != NULL) {
94012099Sjoerg		t = tp->t_tspec;
94112099Sjoerg		/*
94212099Sjoerg		 * If this is the type of an old style function definition,
94312099Sjoerg		 * a better warning is printed in funcdef().
94412099Sjoerg		 */
94512099Sjoerg		if (t == FUNC && !tp->t_proto &&
94612099Sjoerg		    !(to == NOTSPEC && sym->s_osdef)) {
94712099Sjoerg			if (sflag && hflag)
94812099Sjoerg				/* function declaration is not a prototype */
94912099Sjoerg				warning(287);
95012099Sjoerg		}
95112099Sjoerg		if (to == FUNC) {
95212099Sjoerg			if (t == FUNC || t == ARRAY) {
95312099Sjoerg				/* function returns illegal type */
95412099Sjoerg				error(15);
95512099Sjoerg				if (t == FUNC) {
95612099Sjoerg					*tpp = incref(*tpp, PTR);
95712099Sjoerg				} else {
95812099Sjoerg					*tpp = incref((*tpp)->t_subt, PTR);
95912099Sjoerg				}
96012099Sjoerg				return;
96112099Sjoerg			} else if (tp->t_const || tp->t_volatile) {
96212099Sjoerg				if (sflag) {	/* XXX oder better !tflag ? */
96312099Sjoerg					/* function cannot return const... */
96412099Sjoerg					warning(228);
96512099Sjoerg				}
96612099Sjoerg			}
96712099Sjoerg		} if (to == ARRAY) {
96812099Sjoerg			if (t == FUNC) {
96912099Sjoerg				/* array of function is illegal */
97012099Sjoerg				error(16);
97112099Sjoerg				*tpp = gettyp(INT);
97212099Sjoerg				return;
97312099Sjoerg			} else if (t == ARRAY && tp->t_dim == 0) {
97412099Sjoerg				/* null dimension */
97512099Sjoerg				error(17);
97612099Sjoerg				return;
97712099Sjoerg			} else if (t == VOID) {
97812099Sjoerg				/* illegal use of void */
97912099Sjoerg				error(18);
98012099Sjoerg				*tpp = gettyp(INT);
98112099Sjoerg#if 0	/* errors are produced by length() */
98212099Sjoerg			} else if (incompl(tp)) {
98312099Sjoerg				/* array of incomplete type */
98412099Sjoerg				if (sflag) {
98512099Sjoerg					error(301);
98612099Sjoerg				} else {
98712099Sjoerg					warning(301);
98812099Sjoerg				}
98912099Sjoerg#endif
99012099Sjoerg			}
99112099Sjoerg		} else if (to == NOTSPEC && t == VOID) {
99212099Sjoerg			if (dcs->d_ctx == PARG) {
99312099Sjoerg				if (sym->s_scl != ABSTRACT) {
99412099Sjoerg					if (sym->s_name == unnamed)
99512099Sjoerg						lerror("chktyp()");
99612099Sjoerg					/* void param cannot have name: %s */
99712099Sjoerg					error(61, sym->s_name);
99812099Sjoerg					*tpp = gettyp(INT);
99912099Sjoerg				}
100012099Sjoerg			} else if (dcs->d_ctx == ABSTRACT) {
100112099Sjoerg				/* ok */
100212099Sjoerg			} else if (sym->s_scl != TYPEDEF) {
100312099Sjoerg				/* void type for %s */
100412099Sjoerg				error(19, sym->s_name);
100512099Sjoerg				*tpp = gettyp(INT);
100612099Sjoerg			}
100712099Sjoerg		}
100812099Sjoerg		if (t == VOID && to != PTR) {
100912099Sjoerg			if (tp->t_const || tp->t_volatile) {
101012099Sjoerg				/* inappropriate qualifiers with "void" */
101112099Sjoerg				warning(69);
101212099Sjoerg				tp->t_const = tp->t_volatile = 0;
101312099Sjoerg			}
101412099Sjoerg		}
101512099Sjoerg		tpp = &tp->t_subt;
101612099Sjoerg		to = t;
101712099Sjoerg	}
101812099Sjoerg}
101912099Sjoerg
102012099Sjoerg/*
102112099Sjoerg * Process the declarator of a struct/union element.
102212099Sjoerg */
102312099Sjoergsym_t *
102412099Sjoergdecl1str(dsym)
102512099Sjoerg	sym_t	*dsym;
102612099Sjoerg{
102712099Sjoerg	type_t	*tp;
102812099Sjoerg	tspec_t	t;
102912099Sjoerg	int	sz, o, len;
103012099Sjoerg	scl_t	sc;
103112099Sjoerg
103212099Sjoerg	if ((sc = dsym->s_scl) != MOS && sc != MOU)
103312099Sjoerg		lerror("decl1str() 1");
103412099Sjoerg
103512099Sjoerg	if (dcs->d_rdcsym != NULL) {
103612099Sjoerg		if ((sc = dcs->d_rdcsym->s_scl) != MOS && sc != MOU)
103712099Sjoerg			/* should be ensured by storesym() */
103812099Sjoerg			lerror("decl1str() 2");
103912099Sjoerg		if (dsym->s_styp == dcs->d_rdcsym->s_styp) {
104012099Sjoerg			/* duplicate member name: %s */
104112099Sjoerg			error(33, dsym->s_name);
104212099Sjoerg			rmsym(dcs->d_rdcsym);
104312099Sjoerg		}
104412099Sjoerg	}
104512099Sjoerg
104612099Sjoerg	chktyp(dsym);
104712099Sjoerg
104812099Sjoerg	t = (tp = dsym->s_type)->t_tspec;
104912099Sjoerg
105012099Sjoerg	if (dsym->s_field) {
105112099Sjoerg		/*
105212099Sjoerg		 * bit field
105312099Sjoerg		 *
105412099Sjoerg		 * only unsigned und signed int are protable bit-field types
105512099Sjoerg		 *(at least in ANSI C, in traditional C only unsigned int)
105612099Sjoerg		 */
105712099Sjoerg		if (t == CHAR || t == UCHAR || t == SCHAR ||
105812099Sjoerg		    t == SHORT || t == USHORT || t == ENUM) {
105912099Sjoerg			if (sflag) {
106012099Sjoerg				/* bit-field type '%s' invalid in ANSI C */
106112099Sjoerg				warning(273, tyname(tp));
106212099Sjoerg			} else if (pflag) {
106312099Sjoerg				/* nonportable bit-field type */
106412099Sjoerg				warning(34);
106512099Sjoerg			}
106612099Sjoerg		} else if (t == INT && dcs->d_smod == NOTSPEC) {
106712099Sjoerg			if (pflag) {
106812099Sjoerg				/* nonportable bit-field type */
106912099Sjoerg				warning(34);
107012099Sjoerg			}
107112099Sjoerg		} else if (t != INT && t != UINT) {
107212099Sjoerg			/* illegal bit-field type */
107312099Sjoerg			error(35);
107412099Sjoerg			sz = tp->t_flen;
107512099Sjoerg			dsym->s_type = tp = duptyp(gettyp(t = INT));
107612099Sjoerg			if ((tp->t_flen = sz) > size(t))
107712099Sjoerg				tp->t_flen = size(t);
107812099Sjoerg		}
107912099Sjoerg		if ((len = tp->t_flen) < 0 || len > size(t)) {
108012099Sjoerg			/* illegal bit-field size */
108112099Sjoerg			error(36);
108212099Sjoerg			tp->t_flen = size(t);
108312099Sjoerg		} else if (len == 0 && dsym->s_name != unnamed) {
108412099Sjoerg			/* zero size bit-field */
108512099Sjoerg			error(37);
108612099Sjoerg			tp->t_flen = size(t);
108712099Sjoerg		}
108812099Sjoerg		if (dsym->s_scl == MOU) {
108912099Sjoerg			/* illegal use of bit-field */
109012099Sjoerg			error(41);
109112099Sjoerg			dsym->s_type->t_isfield = 0;
109212099Sjoerg			dsym->s_field = 0;
109312099Sjoerg		}
109412099Sjoerg	} else if (t == FUNC) {
109512099Sjoerg		/* function illegal in structure or union */
109612099Sjoerg		error(38);
109712099Sjoerg		dsym->s_type = tp = incref(tp, t = PTR);
109812099Sjoerg	}
109912099Sjoerg
110012099Sjoerg	/*
110112099Sjoerg	 * bit-fields of length 0 are not warned about because length()
110212099Sjoerg	 * does not return the length of the bit-field but the length
110312099Sjoerg	 * of the type the bit-field is packed in (its ok)
110412099Sjoerg	 */
110512099Sjoerg	if ((sz = length(dsym->s_type, dsym->s_name)) == 0) {
110612099Sjoerg		if (t == ARRAY && dsym->s_type->t_dim == 0) {
110712099Sjoerg			/* illegal zero sized structure member: %s */
110812099Sjoerg			warning(39, dsym->s_name);
110912099Sjoerg		}
111012099Sjoerg	}
111112099Sjoerg
111212099Sjoerg	if (dcs->d_ctx == MOU) {
111312099Sjoerg		o = dcs->d_offset;
111412099Sjoerg		dcs->d_offset = 0;
111512099Sjoerg	}
111612099Sjoerg	if (dsym->s_field) {
111712099Sjoerg		align(getbound(tp), tp->t_flen);
111812099Sjoerg		dsym->s_value.v_quad = (dcs->d_offset / size(t)) * size(t);
111912099Sjoerg		tp->t_foffs = dcs->d_offset - (int)dsym->s_value.v_quad;
112012099Sjoerg		dcs->d_offset += tp->t_flen;
112112099Sjoerg	} else {
112212099Sjoerg		align(getbound(tp), 0);
112312099Sjoerg		dsym->s_value.v_quad = dcs->d_offset;
112412099Sjoerg		dcs->d_offset += sz;
112512099Sjoerg	}
112612099Sjoerg	if (dcs->d_ctx == MOU) {
112712099Sjoerg		if (o > dcs->d_offset)
112812099Sjoerg			dcs->d_offset = o;
112912099Sjoerg	}
113012099Sjoerg
113112099Sjoerg	chkfdef(dsym, 0);
113212099Sjoerg
113312099Sjoerg	return (dsym);
113412099Sjoerg}
113512099Sjoerg
113612099Sjoerg/*
113712099Sjoerg * Aligns next structure element as required.
113812099Sjoerg *
113912099Sjoerg * al contains the required alignment, len the length of a bit-field.
114012099Sjoerg */
114112099Sjoergstatic void
114212099Sjoergalign(al, len)
114312099Sjoerg	int	al, len;
114412099Sjoerg{
114512099Sjoerg	int	no;
114612099Sjoerg
114712099Sjoerg	/*
114812099Sjoerg	 * The alignment of the current element becomes the alignment of
114912099Sjoerg	 * the struct/union if it is larger than the current alignment
115012099Sjoerg	 * of the struct/union.
115112099Sjoerg	 */
115212099Sjoerg	if (al > dcs->d_stralign)
115312099Sjoerg		dcs->d_stralign = al;
115412099Sjoerg
115512099Sjoerg	no = (dcs->d_offset + (al - 1)) & ~(al - 1);
115612099Sjoerg	if (len == 0 || dcs->d_offset + len > no)
115712099Sjoerg		dcs->d_offset = no;
115812099Sjoerg}
115912099Sjoerg
116012099Sjoerg/*
116112099Sjoerg * Remember the width of the field in its type structure.
116212099Sjoerg */
116312099Sjoergsym_t *
116412099Sjoergbitfield(dsym, len)
116512099Sjoerg	sym_t	*dsym;
116612099Sjoerg	int	len;
116712099Sjoerg{
116812099Sjoerg	if (dsym == NULL) {
116912099Sjoerg		dsym = getblk(sizeof (sym_t));
117012099Sjoerg		dsym->s_name = unnamed;
117112099Sjoerg		dsym->s_kind = FMOS;
117212099Sjoerg		dsym->s_scl = MOS;
117312099Sjoerg		dsym->s_type = gettyp(INT);
117412099Sjoerg		dsym->s_blklev = -1;
117512099Sjoerg	}
117612099Sjoerg	dsym->s_type = duptyp(dsym->s_type);
117712099Sjoerg	dsym->s_type->t_isfield = 1;
117812099Sjoerg	dsym->s_type->t_flen = len;
117912099Sjoerg	dsym->s_field = 1;
118012099Sjoerg	return (dsym);
118112099Sjoerg}
118212099Sjoerg
118312099Sjoerg/*
118412099Sjoerg * Collect informations about a sequence of asterisks and qualifiers
118512099Sjoerg * in a list of type pqinf_t.
118612099Sjoerg * Qualifiers refer always to the left asterisk. The rightmost asterisk
118712099Sjoerg * will be at the top of the list.
118812099Sjoerg */
118912099Sjoergpqinf_t *
119012099Sjoergmergepq(p1, p2)
119112099Sjoerg	pqinf_t	*p1, *p2;
119212099Sjoerg{
119312099Sjoerg	pqinf_t	*p;
119412099Sjoerg
119512099Sjoerg	if (p2->p_pcnt != 0) {
119612099Sjoerg		/* left '*' at the end of the list */
119712099Sjoerg		for (p = p2; p->p_nxt != NULL; p = p->p_nxt) ;
119812099Sjoerg		p->p_nxt = p1;
119912099Sjoerg		return (p2);
120012099Sjoerg	} else {
120112099Sjoerg		if (p2->p_const) {
120212099Sjoerg			if (p1->p_const) {
120312099Sjoerg				/* duplicate %s */
120412099Sjoerg				warning(10, "const");
120512099Sjoerg			}
120612099Sjoerg			p1->p_const = 1;
120712099Sjoerg		}
120812099Sjoerg		if (p2->p_volatile) {
120912099Sjoerg			if (p1->p_volatile) {
121012099Sjoerg				/* duplicate %s */
121112099Sjoerg				warning(10, "volatile");
121212099Sjoerg			}
121312099Sjoerg			p1->p_volatile = 1;
121412099Sjoerg		}
121512099Sjoerg		free(p2);
121612099Sjoerg		return (p1);
121712099Sjoerg	}
121812099Sjoerg}
121912099Sjoerg
122012099Sjoerg/*
122112099Sjoerg * Followint 3 functions extend the type of a declarator with
122212099Sjoerg * pointer, function and array types.
122312099Sjoerg *
122412099Sjoerg * The current type is the Type built by deftyp() (dcs->d_type) and
122512099Sjoerg * pointer, function and array types already added for this
122612099Sjoerg * declarator. The new type extension is inserted between both.
122712099Sjoerg */
122812099Sjoergsym_t *
122912099Sjoergaddptr(decl, pi)
123012099Sjoerg	sym_t	*decl;
123112099Sjoerg	pqinf_t	*pi;
123212099Sjoerg{
123312099Sjoerg	type_t	**tpp, *tp;
123412099Sjoerg	pqinf_t	*npi;
123512099Sjoerg
123612099Sjoerg	tpp = &decl->s_type;
123712099Sjoerg	while (*tpp != dcs->d_type)
123812099Sjoerg		tpp = &(*tpp)->t_subt;
123912099Sjoerg
124012099Sjoerg	while (pi != NULL) {
124112099Sjoerg		*tpp = tp = getblk(sizeof (type_t));
124212099Sjoerg		tp->t_tspec = PTR;
124312099Sjoerg		tp->t_const = pi->p_const;
124412099Sjoerg		tp->t_volatile = pi->p_volatile;
124512099Sjoerg		*(tpp = &tp->t_subt) = dcs->d_type;
124612099Sjoerg		npi = pi->p_nxt;
124712099Sjoerg		free(pi);
124812099Sjoerg		pi = npi;
124912099Sjoerg	}
125012099Sjoerg	return (decl);
125112099Sjoerg}
125212099Sjoerg
125312099Sjoerg/*
125412099Sjoerg * If a dimension was specified, dim is 1, otherwise 0
125512099Sjoerg * n is the specified dimension
125612099Sjoerg */
125712099Sjoergsym_t *
125812099Sjoergaddarray(decl, dim, n)
125912099Sjoerg	sym_t	*decl;
126012099Sjoerg	int	dim, n;
126112099Sjoerg{
126212099Sjoerg	type_t	**tpp, *tp;
126312099Sjoerg
126412099Sjoerg	tpp = &decl->s_type;
126512099Sjoerg	while (*tpp != dcs->d_type)
126612099Sjoerg		tpp = &(*tpp)->t_subt;
126712099Sjoerg
126812099Sjoerg	*tpp = tp = getblk(sizeof (type_t));
126912099Sjoerg	tp->t_tspec = ARRAY;
127012099Sjoerg	tp->t_subt = dcs->d_type;
127112099Sjoerg	tp->t_dim = n;
127212099Sjoerg
127312099Sjoerg	if (n < 0) {
127412099Sjoerg		/* zero or negative array dimension */
127512099Sjoerg		error(20);
127612099Sjoerg		n = 0;
127712099Sjoerg	} else if (n == 0 && dim) {
127812099Sjoerg		/* zero or negative array dimension */
127912099Sjoerg		warning(20);
128012099Sjoerg	} else if (n == 0 && !dim) {
128112099Sjoerg		/* is incomplete type */
128212099Sjoerg		setcompl(tp, 1);
128312099Sjoerg	}
128412099Sjoerg
128512099Sjoerg	return (decl);
128612099Sjoerg}
128712099Sjoerg
128812099Sjoergsym_t *
128912099Sjoergaddfunc(decl, args)
129012099Sjoerg	sym_t	*decl, *args;
129112099Sjoerg{
129212099Sjoerg	type_t	**tpp, *tp;
129312099Sjoerg
129412099Sjoerg	if (dcs->d_proto) {
129512099Sjoerg		if (tflag)
129612099Sjoerg			/* function prototypes are illegal in traditional C */
129712099Sjoerg			warning(270);
129812099Sjoerg		args = nsfunc(decl, args);
129912099Sjoerg	} else {
130012099Sjoerg		osfunc(decl, args);
130112099Sjoerg	}
130212099Sjoerg
130312099Sjoerg	/*
130412099Sjoerg	 * The symbols are removed from the symbol table by popdecl() after
130512099Sjoerg	 * addfunc(). To be able to restore them if this is a function
130612099Sjoerg	 * definition, a pointer to the list of all symbols is stored in
130712099Sjoerg	 * dcs->d_nxt->d_fpsyms. Also a list of the arguments (concatenated
130812099Sjoerg	 * by s_nxt) is stored in dcs->d_nxt->d_fargs.
130912099Sjoerg	 * (dcs->d_nxt must be used because *dcs is the declaration stack
131012099Sjoerg	 * element created for the list of params and is removed after
131112099Sjoerg	 * addfunc())
131212099Sjoerg	 */
131312099Sjoerg	if (dcs->d_nxt->d_ctx == EXTERN &&
131412099Sjoerg	    decl->s_type == dcs->d_nxt->d_type) {
131512099Sjoerg		dcs->d_nxt->d_fpsyms = dcs->d_dlsyms;
131612099Sjoerg		dcs->d_nxt->d_fargs = args;
131712099Sjoerg	}
131812099Sjoerg
131912099Sjoerg	tpp = &decl->s_type;
132012099Sjoerg	while (*tpp != dcs->d_nxt->d_type)
132112099Sjoerg		tpp = &(*tpp)->t_subt;
132212099Sjoerg
132312099Sjoerg	*tpp = tp = getblk(sizeof (type_t));
132412099Sjoerg	tp->t_tspec = FUNC;
132512099Sjoerg	tp->t_subt = dcs->d_nxt->d_type;
132612099Sjoerg	if ((tp->t_proto = dcs->d_proto) != 0)
132712099Sjoerg		tp->t_args = args;
132812099Sjoerg	tp->t_vararg = dcs->d_vararg;
132912099Sjoerg
133012099Sjoerg	return (decl);
133112099Sjoerg}
133212099Sjoerg
133312099Sjoerg/*
133412099Sjoerg * Called for new style function declarations.
133512099Sjoerg */
133612099Sjoerg/* ARGSUSED */
133712099Sjoergstatic sym_t *
133812099Sjoergnsfunc(decl, args)
133912099Sjoerg	sym_t	*decl, *args;
134012099Sjoerg{
134112099Sjoerg	sym_t	*arg, *sym;
134212099Sjoerg	scl_t	sc;
134312099Sjoerg	int	n;
134412099Sjoerg
134512099Sjoerg	/*
134612099Sjoerg	 * Declarations of structs/unions/enums in param lists are legal,
134712099Sjoerg	 * but senseless.
134812099Sjoerg	 */
134912099Sjoerg	for (sym = dcs->d_dlsyms; sym != NULL; sym = sym->s_dlnxt) {
135012099Sjoerg		sc = sym->s_scl;
135112099Sjoerg		if (sc == STRTAG || sc == UNIONTAG || sc == ENUMTAG) {
135212099Sjoerg			/* dubious tag declaration: %s %s */
135312099Sjoerg			warning(85, scltoa(sc), sym->s_name);
135412099Sjoerg		}
135512099Sjoerg	}
135612099Sjoerg
135712099Sjoerg	n = 1;
135812099Sjoerg	for (arg = args; arg != NULL; arg = arg->s_nxt) {
135912099Sjoerg		if (arg->s_type->t_tspec == VOID) {
136012099Sjoerg			if (n > 1 || arg->s_nxt != NULL) {
136112099Sjoerg				/* "void" must be sole parameter */
136212099Sjoerg				error(60);
136312099Sjoerg				arg->s_type = gettyp(INT);
136412099Sjoerg			}
136512099Sjoerg		}
136612099Sjoerg		n++;
136712099Sjoerg	}
136812099Sjoerg
136912099Sjoerg	/* return NULL if first param is VOID */
137012099Sjoerg	return (args != NULL && args->s_type->t_tspec != VOID ? args : NULL);
137112099Sjoerg}
137212099Sjoerg
137312099Sjoerg/*
137412099Sjoerg * Called for old style function declarations.
137512099Sjoerg */
137612099Sjoergstatic void
137712099Sjoergosfunc(decl, args)
137812099Sjoerg	sym_t	*decl, *args;
137912099Sjoerg{
138012099Sjoerg	/*
138112099Sjoerg	 * Remember list of params only if this is really seams to be
138212099Sjoerg	 * a function definition.
138312099Sjoerg	 */
138412099Sjoerg	if (dcs->d_nxt->d_ctx == EXTERN &&
138512099Sjoerg	    decl->s_type == dcs->d_nxt->d_type) {
138612099Sjoerg		/*
138712099Sjoerg		 * We assume that this becomes a function definition. If
138812099Sjoerg		 * we are wrong, its corrected in chkfdef().
138912099Sjoerg		 */
139012099Sjoerg		if (args != NULL) {
139112099Sjoerg			decl->s_osdef = 1;
139212099Sjoerg			decl->s_args = args;
139312099Sjoerg		}
139412099Sjoerg	} else {
139512099Sjoerg		if (args != NULL)
139612099Sjoerg			/* function prototype parameters must have types */
139712099Sjoerg			warning(62);
139812099Sjoerg	}
139912099Sjoerg}
140012099Sjoerg
140112099Sjoerg/*
140212099Sjoerg * Lists of Identifiers in functions declarations are allowed only if
140312099Sjoerg * its also a function definition. If this is not the case, print a
140412099Sjoerg * error message.
140512099Sjoerg */
140612099Sjoergvoid
140712099Sjoergchkfdef(sym, msg)
140812099Sjoerg	sym_t	*sym;
140912099Sjoerg	int	msg;
141012099Sjoerg{
141112099Sjoerg	if (sym->s_osdef) {
141212099Sjoerg		if (msg) {
141312099Sjoerg			/* incomplete or misplaced function definition */
141412099Sjoerg			error(22);
141512099Sjoerg		}
141612099Sjoerg		sym->s_osdef = 0;
141712099Sjoerg		sym->s_args = NULL;
141812099Sjoerg	}
141912099Sjoerg}
142012099Sjoerg
142112099Sjoerg/*
142212099Sjoerg * Process the name in a declarator.
142312099Sjoerg * If the symbol does already exists, a new one is created.
142412099Sjoerg * The symbol becomes one of the storage classes EXTERN, STATIC, AUTO or
142512099Sjoerg * TYPEDEF.
142612099Sjoerg * s_def and s_reg are valid after dname().
142712099Sjoerg */
142812099Sjoergsym_t *
142912099Sjoergdname(sym)
143012099Sjoerg	sym_t	*sym;
143112099Sjoerg{
143212099Sjoerg	scl_t	sc;
143312099Sjoerg
143412099Sjoerg	if (sym->s_scl == NOSCL) {
143512099Sjoerg		dcs->d_rdcsym = NULL;
143612099Sjoerg	} else if (sym->s_defarg) {
143712099Sjoerg		sym->s_defarg = 0;
143812099Sjoerg		dcs->d_rdcsym = NULL;
143912099Sjoerg	} else {
144012099Sjoerg		dcs->d_rdcsym = sym;
144112099Sjoerg		sym = pushdown(sym);
144212099Sjoerg	}
144312099Sjoerg
144412099Sjoerg	switch (dcs->d_ctx) {
144512099Sjoerg	case MOS:
144612099Sjoerg	case MOU:
144712099Sjoerg		/* Parent setzen */
144812099Sjoerg		sym->s_styp = dcs->d_tagtyp->t_str;
144912099Sjoerg		sym->s_def = DEF;
145012099Sjoerg		sym->s_value.v_tspec = INT;
145112099Sjoerg		sc = dcs->d_ctx;
145212099Sjoerg		break;
145312099Sjoerg	case EXTERN:
145412099Sjoerg		/*
145512099Sjoerg		 * static and external symbols without "extern" are
145612099Sjoerg		 * considered to be tentative defined, external
145712099Sjoerg		 * symbols with "extern" are declared, and typedef names
145812099Sjoerg		 * are defined. Tentative defined and declared symbols
145912099Sjoerg		 * may become defined if an initializer is present or
146012099Sjoerg		 * this is a function definition.
146112099Sjoerg		 */
146212099Sjoerg		if ((sc = dcs->d_scl) == NOSCL) {
146312099Sjoerg			sc = EXTERN;
146412099Sjoerg			sym->s_def = TDEF;
146512099Sjoerg		} else if (sc == STATIC) {
146612099Sjoerg			sym->s_def = TDEF;
146712099Sjoerg		} else if (sc == TYPEDEF) {
146812099Sjoerg			sym->s_def = DEF;
146912099Sjoerg		} else if (sc == EXTERN) {
147012099Sjoerg			sym->s_def = DECL;
147112099Sjoerg		} else {
147212099Sjoerg			lerror("dname() 1");
147312099Sjoerg		}
147412099Sjoerg		break;
147512099Sjoerg	case PARG:
147612099Sjoerg		sym->s_arg = 1;
147712099Sjoerg		/* FALLTHROUGH */
147812099Sjoerg	case ARG:
147912099Sjoerg		if ((sc = dcs->d_scl) == NOSCL) {
148012099Sjoerg			sc = AUTO;
148112099Sjoerg		} else if (sc == REG) {
148212099Sjoerg			sym->s_reg = 1;
148312099Sjoerg			sc = AUTO;
148412099Sjoerg		} else {
148512099Sjoerg			lerror("dname() 2");
148612099Sjoerg		}
148712099Sjoerg		sym->s_def = DEF;
148812099Sjoerg		break;
148912099Sjoerg	case AUTO:
149012099Sjoerg		if ((sc = dcs->d_scl) == NOSCL) {
149112099Sjoerg			/*
149212099Sjoerg			 * XXX somewhat ugly because we dont know whether
149312099Sjoerg			 * this is AUTO or EXTERN (functions). If we are
149412099Sjoerg			 * wrong it must be corrected in decl1loc(), where
149512099Sjoerg			 * we have the neccessary type information.
149612099Sjoerg			 */
149712099Sjoerg			sc = AUTO;
149812099Sjoerg			sym->s_def = DEF;
149912099Sjoerg		} else if (sc == AUTO || sc == STATIC || sc == TYPEDEF) {
150012099Sjoerg			sym->s_def = DEF;
150112099Sjoerg		} else if (sc == REG) {
150212099Sjoerg			sym->s_reg = 1;
150312099Sjoerg			sc = AUTO;
150412099Sjoerg			sym->s_def = DEF;
150512099Sjoerg		} else if (sc == EXTERN) {
150612099Sjoerg			sym->s_def = DECL;
150712099Sjoerg		} else {
150812099Sjoerg			lerror("dname() 3");
150912099Sjoerg		}
151012099Sjoerg		break;
151112099Sjoerg	default:
151212099Sjoerg		lerror("dname() 4");
151312099Sjoerg	}
151412099Sjoerg	sym->s_scl = sc;
151512099Sjoerg
151612099Sjoerg	sym->s_type = dcs->d_type;
151712099Sjoerg
151812099Sjoerg	dcs->d_fpsyms = NULL;
151912099Sjoerg
152012099Sjoerg	return (sym);
152112099Sjoerg}
152212099Sjoerg
152312099Sjoerg/*
152412099Sjoerg * Process a name in the list of formal params in an old style function
152512099Sjoerg * definition.
152612099Sjoerg */
152712099Sjoergsym_t *
152812099Sjoerginame(sym)
152912099Sjoerg	sym_t	*sym;
153012099Sjoerg{
153112099Sjoerg	if (sym->s_scl != NOSCL) {
153212099Sjoerg		if (blklev == sym->s_blklev) {
153312099Sjoerg			/* redeclaration of formal parameter %s */
153412099Sjoerg			error(21, sym->s_name);
153512099Sjoerg			if (!sym->s_defarg)
153612099Sjoerg				lerror("iname()");
153712099Sjoerg		}
153812099Sjoerg		sym = pushdown(sym);
153912099Sjoerg	}
154012099Sjoerg	sym->s_type = gettyp(INT);
154112099Sjoerg	sym->s_scl = AUTO;
154212099Sjoerg	sym->s_def = DEF;
154312099Sjoerg	sym->s_defarg = sym->s_arg = 1;
154412099Sjoerg	return (sym);
154512099Sjoerg}
154612099Sjoerg
154712099Sjoerg/*
154812099Sjoerg * Create the type of a tag.
154912099Sjoerg *
155012099Sjoerg * tag points to the symbol table entry of the tag
155112099Sjoerg * kind is the kind of the tag (STRUCT/UNION/ENUM)
155212099Sjoerg * decl is 1 if the type of the tag will be completed in this declaration
155312099Sjoerg * (the following token is T_LBRACE)
155412099Sjoerg * semi is 1 if the following token is T_SEMI
155512099Sjoerg */
155612099Sjoergtype_t *
155712099Sjoergmktag(tag, kind, decl, semi)
155812099Sjoerg	sym_t	*tag;
155912099Sjoerg	tspec_t	kind;
156012099Sjoerg	int	decl, semi;
156112099Sjoerg{
156212099Sjoerg	scl_t	scl;
156312099Sjoerg	type_t	*tp;
156412099Sjoerg
156512099Sjoerg	if (kind == STRUCT) {
156612099Sjoerg		scl = STRTAG;
156712099Sjoerg	} else if (kind == UNION) {
156812099Sjoerg		scl = UNIONTAG;
156912099Sjoerg	} else if (kind == ENUM) {
157012099Sjoerg		scl = ENUMTAG;
157112099Sjoerg	} else {
157212099Sjoerg		lerror("mktag()");
157312099Sjoerg	}
157412099Sjoerg
157512099Sjoerg	if (tag != NULL) {
157612099Sjoerg		if (tag->s_scl != NOSCL) {
157712099Sjoerg			tag = newtag(tag, scl, decl, semi);
157812099Sjoerg		} else {
157912099Sjoerg			/* a new tag, no empty declaration */
158012099Sjoerg			dcs->d_nxt->d_nedecl = 1;
158112099Sjoerg			if (scl == ENUMTAG && !decl) {
158212099Sjoerg				if (!tflag && (sflag || pflag))
158312099Sjoerg					/* forward reference to enum type */
158412099Sjoerg					warning(42);
158512099Sjoerg			}
158612099Sjoerg		}
158712099Sjoerg		if (tag->s_scl == NOSCL) {
158812099Sjoerg			tag->s_scl = scl;
158912099Sjoerg			tag->s_type = tp = getblk(sizeof (type_t));
159012099Sjoerg		} else {
159112099Sjoerg			tp = tag->s_type;
159212099Sjoerg		}
159312099Sjoerg	} else {
159412099Sjoerg		tag = getblk(sizeof (sym_t));
159512099Sjoerg		tag->s_name = unnamed;
159612099Sjoerg		STRUCT_ASSIGN(tag->s_dpos, curr_pos);
159712099Sjoerg		tag->s_kind = FTAG;
159812099Sjoerg		tag->s_scl = scl;
159912099Sjoerg		tag->s_blklev = -1;
160012099Sjoerg		tag->s_type = tp = getblk(sizeof (type_t));
160112099Sjoerg		dcs->d_nxt->d_nedecl = 1;
160212099Sjoerg	}
160312099Sjoerg
160412099Sjoerg	if (tp->t_tspec == NOTSPEC) {
160512099Sjoerg		tp->t_tspec = kind;
160612099Sjoerg		if (kind != ENUM) {
160712099Sjoerg			tp->t_str = getblk(sizeof (str_t));
160812099Sjoerg			tp->t_str->align = CHAR_BIT;
160912099Sjoerg			tp->t_str->stag = tag;
161012099Sjoerg		} else {
161112099Sjoerg			tp->t_isenum = 1;
161212099Sjoerg			tp->t_enum = getblk(sizeof (enum_t));
161312099Sjoerg			tp->t_enum->etag = tag;
161412099Sjoerg		}
161512099Sjoerg		/* ist unvollstaendiger Typ */
161612099Sjoerg		setcompl(tp, 1);
161712099Sjoerg	}
161812099Sjoerg
161912099Sjoerg	return (tp);
162012099Sjoerg}
162112099Sjoerg
162212099Sjoerg/*
162312099Sjoerg * Checks all possible cases of tag redeclarations.
162412099Sjoerg * decl is 1 if T_LBRACE follows
162512099Sjoerg * semi is 1 if T_SEMI follows
162612099Sjoerg */
162712099Sjoergstatic sym_t *
162812099Sjoergnewtag(tag, scl, decl, semi)
162912099Sjoerg	sym_t	*tag;
163012099Sjoerg	scl_t	scl;
163112099Sjoerg	int	decl, semi;
163212099Sjoerg{
163312099Sjoerg	if (tag->s_blklev < blklev) {
163412099Sjoerg		if (semi) {
163512099Sjoerg			/* "struct a;" */
163612099Sjoerg			if (!tflag) {
163712099Sjoerg				if (!sflag)
163812099Sjoerg					/* decl. introduces new type ... */
163912099Sjoerg					warning(44, scltoa(scl), tag->s_name);
164012099Sjoerg				tag = pushdown(tag);
164112099Sjoerg			} else if (tag->s_scl != scl) {
164212099Sjoerg				/* base type is really "%s %s" */
164312099Sjoerg				warning(45, scltoa(tag->s_scl), tag->s_name);
164412099Sjoerg			}
164512099Sjoerg			dcs->d_nxt->d_nedecl = 1;
164612099Sjoerg		} else if (decl) {
164712099Sjoerg			/* "struct a { ..." */
164812099Sjoerg			if (hflag)
164912099Sjoerg				/* redefinition hides earlier one: %s */
165012099Sjoerg				warning(43, tag->s_name);
165112099Sjoerg			tag = pushdown(tag);
165212099Sjoerg			dcs->d_nxt->d_nedecl = 1;
165312099Sjoerg		} else if (tag->s_scl != scl) {
165412099Sjoerg			/* base type is really "%s %s" */
165512099Sjoerg			warning(45, scltoa(tag->s_scl), tag->s_name);
165612099Sjoerg			/* declaration introduces new type in ANSI C: %s %s */
165712099Sjoerg			if (!sflag)
165812099Sjoerg				warning(44, scltoa(scl), tag->s_name);
165912099Sjoerg			tag = pushdown(tag);
166012099Sjoerg			dcs->d_nxt->d_nedecl = 1;
166112099Sjoerg		}
166212099Sjoerg	} else {
166312099Sjoerg		if (tag->s_scl != scl) {
166412099Sjoerg			/* (%s) tag redeclared */
166512099Sjoerg			error(46, scltoa(tag->s_scl));
166612099Sjoerg			prevdecl(-1, tag);
166712099Sjoerg			tag = pushdown(tag);
166812099Sjoerg			dcs->d_nxt->d_nedecl = 1;
166912099Sjoerg		} else if (decl && !incompl(tag->s_type)) {
167012099Sjoerg			/* (%s) tag redeclared */
167112099Sjoerg			error(46, scltoa(tag->s_scl));
167212099Sjoerg			prevdecl(-1, tag);
167312099Sjoerg			tag = pushdown(tag);
167412099Sjoerg			dcs->d_nxt->d_nedecl = 1;
167512099Sjoerg		} else if (semi || decl) {
167612099Sjoerg			dcs->d_nxt->d_nedecl = 1;
167712099Sjoerg		}
167812099Sjoerg	}
167912099Sjoerg	return (tag);
168012099Sjoerg}
168112099Sjoerg
168212099Sjoergconst char *
168312099Sjoergscltoa(sc)
168412099Sjoerg	scl_t	sc;
168512099Sjoerg{
168612099Sjoerg	const	char *s;
168712099Sjoerg
168812099Sjoerg	switch (sc) {
168912099Sjoerg	case EXTERN:	s = "extern";	break;
169012099Sjoerg	case STATIC:	s = "static";	break;
169112099Sjoerg	case AUTO:	s = "auto";	break;
169212099Sjoerg	case REG:	s = "register";	break;
169312099Sjoerg	case TYPEDEF:	s = "typedef";	break;
169412099Sjoerg	case STRTAG:	s = "struct";	break;
169512099Sjoerg	case UNIONTAG:	s = "union";	break;
169612099Sjoerg	case ENUMTAG:	s = "enum";	break;
169712099Sjoerg	default:	lerror("tagttoa()");
169812099Sjoerg	}
169912099Sjoerg	return (s);
170012099Sjoerg}
170112099Sjoerg
170212099Sjoerg/*
170312099Sjoerg * Completes the type of a tag in a struct/union/enum declaration.
170412099Sjoerg * tp points to the type of the, tag, fmem to the list of members/enums.
170512099Sjoerg */
170612099Sjoergtype_t *
170712099Sjoergcompltag(tp, fmem)
170812099Sjoerg	type_t	*tp;
170912099Sjoerg	sym_t	*fmem;
171012099Sjoerg{
171112099Sjoerg	tspec_t	t;
171212099Sjoerg	str_t	*sp;
171312099Sjoerg	int	n;
171412099Sjoerg	sym_t	*mem;
171512099Sjoerg
171612099Sjoerg	/* from now a complete type */
171712099Sjoerg	setcompl(tp, 0);
171812099Sjoerg
171912099Sjoerg	if ((t = tp->t_tspec) != ENUM) {
172012099Sjoerg		align(dcs->d_stralign, 0);
172112099Sjoerg		sp = tp->t_str;
172212099Sjoerg		sp->align = dcs->d_stralign;
172312099Sjoerg		sp->size = dcs->d_offset;
172412099Sjoerg		sp->memb = fmem;
172512099Sjoerg		if (sp->size == 0) {
172612099Sjoerg			/* zero sized %s */
172712099Sjoerg			(void)gnuism(47, ttab[t].tt_name);
172812099Sjoerg		} else {
172912099Sjoerg			n = 0;
173012099Sjoerg			for (mem = fmem; mem != NULL; mem = mem->s_nxt) {
173112099Sjoerg				if (mem->s_name != unnamed)
173212099Sjoerg					n++;
173312099Sjoerg			}
173412099Sjoerg			if (n == 0) {
173512099Sjoerg				/* %s has no named members */
173612099Sjoerg				warning(65,
173712099Sjoerg					t == STRUCT ? "structure" : "union");
173812099Sjoerg			}
173912099Sjoerg		}
174012099Sjoerg	} else {
174112099Sjoerg		tp->t_enum->elem = fmem;
174212099Sjoerg	}
174312099Sjoerg	return (tp);
174412099Sjoerg}
174512099Sjoerg
174612099Sjoerg/*
174712099Sjoerg * Processes the name of an enumerator in en enum declaration.
174812099Sjoerg *
174912099Sjoerg * sym points to the enumerator
175012099Sjoerg * val is the value of the enumerator
175112099Sjoerg * impl is 1 if the the value of the enumerator was not explicit specified.
175212099Sjoerg */
175312099Sjoergsym_t *
175412099Sjoergename(sym, val, impl)
175512099Sjoerg	sym_t	*sym;
175612099Sjoerg	int	val, impl;
175712099Sjoerg{
175812099Sjoerg	if (sym->s_scl) {
175912099Sjoerg		if (sym->s_blklev == blklev) {
176012099Sjoerg			/* no hflag, because this is illegal!!! */
176112099Sjoerg			if (sym->s_arg) {
176212099Sjoerg				/* enumeration constant hides parameter: %s */
176312099Sjoerg				warning(57, sym->s_name);
176412099Sjoerg			} else {
176512099Sjoerg				/* redeclaration of %s */
176612099Sjoerg				error(27, sym->s_name);
176712099Sjoerg				/*
176812099Sjoerg				 * inside blocks it should not too complicated
176912099Sjoerg				 * to find the position of the previous
177012099Sjoerg				 * declaration
177112099Sjoerg				 */
177212099Sjoerg				if (blklev == 0)
177312099Sjoerg					prevdecl(-1, sym);
177412099Sjoerg			}
177512099Sjoerg		} else {
177612099Sjoerg			if (hflag)
177712099Sjoerg				/* redefinition hides earlier one: %s */
177812099Sjoerg				warning(43, sym->s_name);
177912099Sjoerg		}
178012099Sjoerg		sym = pushdown(sym);
178112099Sjoerg	}
178212099Sjoerg	sym->s_scl = ENUMCON;
178312099Sjoerg	sym->s_type = dcs->d_tagtyp;
178412099Sjoerg	sym->s_value.v_tspec = INT;
178512099Sjoerg	sym->s_value.v_quad = val;
178612099Sjoerg	if (impl && val - 1 == INT_MAX) {
178712099Sjoerg		/* overflow in enumeration values: %s */
178812099Sjoerg		warning(48, sym->s_name);
178912099Sjoerg	}
179012099Sjoerg	enumval = val + 1;
179112099Sjoerg	return (sym);
179212099Sjoerg}
179312099Sjoerg
179412099Sjoerg/*
179512099Sjoerg * Process a single external declarator.
179612099Sjoerg */
179712099Sjoergvoid
179812099Sjoergdecl1ext(dsym, initflg)
179912099Sjoerg	sym_t	*dsym;
180012099Sjoerg	int	initflg;
180112099Sjoerg{
180212099Sjoerg	int	warn, rval, redec;
180312099Sjoerg	sym_t	*rdsym;
180412099Sjoerg
180512099Sjoerg	chkfdef(dsym, 1);
180612099Sjoerg
180712099Sjoerg	chktyp(dsym);
180812099Sjoerg
180912099Sjoerg	if (initflg && !(initerr = chkinit(dsym)))
181012099Sjoerg		dsym->s_def = DEF;
181112099Sjoerg
181212099Sjoerg	/*
181312099Sjoerg	 * Declarations of functions are marked as "tentative" in dname().
181412099Sjoerg	 * This is wrong because there are no tentative function
181512099Sjoerg	 * definitions.
181612099Sjoerg	 */
181712099Sjoerg	if (dsym->s_type->t_tspec == FUNC && dsym->s_def == TDEF)
181812099Sjoerg		dsym->s_def = DECL;
181912099Sjoerg
182012099Sjoerg	if (dcs->d_inline) {
182112099Sjoerg		if (dsym->s_type->t_tspec == FUNC) {
182212099Sjoerg			dsym->s_inline = 1;
182312099Sjoerg		} else {
182412099Sjoerg			/* variable declared inline: %s */
182512099Sjoerg			warning(268, dsym->s_name);
182612099Sjoerg		}
182712099Sjoerg	}
182812099Sjoerg
182912099Sjoerg	/* Write the declaration into the output file */
183012099Sjoerg	if (plibflg && llibflg &&
183112099Sjoerg	    dsym->s_type->t_tspec == FUNC && dsym->s_type->t_proto) {
183212099Sjoerg		/*
183312099Sjoerg		 * With both LINTLIBRARY and PROTOLIB the prototyp is
183412099Sjoerg		 * written as a function definition to the output file.
183512099Sjoerg		 */
183612099Sjoerg		rval = dsym->s_type->t_subt->t_tspec != VOID;
183712099Sjoerg		outfdef(dsym, &dsym->s_dpos, rval, 0, NULL);
183812099Sjoerg	} else {
183912099Sjoerg		outsym(dsym, dsym->s_scl, dsym->s_def);
184012099Sjoerg	}
184112099Sjoerg
184212099Sjoerg	if ((rdsym = dcs->d_rdcsym) != NULL) {
184312099Sjoerg
184412099Sjoerg		/*
184512099Sjoerg		 * If the old symbol stems from a old style function definition
184612099Sjoerg		 * we have remembered the params in rdsmy->s_args and compare
184712099Sjoerg		 * them with the params of the prototype.
184812099Sjoerg		 */
184912099Sjoerg		if (rdsym->s_osdef && dsym->s_type->t_proto) {
185012099Sjoerg			redec = chkosdef(rdsym, dsym);
185112099Sjoerg		} else {
185212099Sjoerg			redec = 0;
185312099Sjoerg		}
185412099Sjoerg
185512099Sjoerg		if (!redec && !isredec(dsym, (warn = 0, &warn))) {
185612099Sjoerg
185712099Sjoerg			if (warn) {
185812099Sjoerg				/* redeclaration of %s */
185912099Sjoerg				(*(sflag ? error : warning))(27, dsym->s_name);
186012099Sjoerg				prevdecl(-1, rdsym);
186112099Sjoerg			}
186212099Sjoerg
186312099Sjoerg			/*
186412099Sjoerg			 * Overtake the rememberd params if the new symbol
186512099Sjoerg			 * is not a prototype.
186612099Sjoerg			 */
186712099Sjoerg			if (rdsym->s_osdef && !dsym->s_type->t_proto) {
186812099Sjoerg				dsym->s_osdef = rdsym->s_osdef;
186912099Sjoerg				dsym->s_args = rdsym->s_args;
187012099Sjoerg				STRUCT_ASSIGN(dsym->s_dpos, rdsym->s_dpos);
187112099Sjoerg			}
187212099Sjoerg
187312099Sjoerg			/*
187412099Sjoerg			 * Remember the position of the declaration if the
187512099Sjoerg			 * old symbol was a prototype and the new is not.
187612099Sjoerg			 * Also remember the position if the old symbol
187712099Sjoerg			 * was defined and the new is not.
187812099Sjoerg			 */
187912099Sjoerg			if (rdsym->s_type->t_proto && !dsym->s_type->t_proto) {
188012099Sjoerg				STRUCT_ASSIGN(dsym->s_dpos, rdsym->s_dpos);
188112099Sjoerg			} else if (rdsym->s_def == DEF && dsym->s_def != DEF) {
188212099Sjoerg				STRUCT_ASSIGN(dsym->s_dpos, rdsym->s_dpos);
188312099Sjoerg			}
188412099Sjoerg
188512099Sjoerg			/*
188612099Sjoerg			 * Copy informations about usage of the name into
188712099Sjoerg			 * the new symbol.
188812099Sjoerg			 */
188912099Sjoerg			cpuinfo(dsym, rdsym);
189012099Sjoerg
189112099Sjoerg			/* Once a name is defined, it remains defined. */
189212099Sjoerg			if (rdsym->s_def == DEF)
189312099Sjoerg				dsym->s_def = DEF;
189412099Sjoerg
189512099Sjoerg			/* once a function is inline, it remains inline */
189612099Sjoerg			if (rdsym->s_inline)
189712099Sjoerg				dsym->s_inline = 1;
189812099Sjoerg
189912099Sjoerg			compltyp(dsym, rdsym);
190012099Sjoerg
190112099Sjoerg		}
190212099Sjoerg
190312099Sjoerg		rmsym(rdsym);
190412099Sjoerg	}
190512099Sjoerg
190612099Sjoerg	if (dsym->s_scl == TYPEDEF) {
190712099Sjoerg		dsym->s_type = duptyp(dsym->s_type);
190812099Sjoerg		dsym->s_type->t_typedef = 1;
190912099Sjoerg		settdsym(dsym->s_type, dsym);
191012099Sjoerg	}
191112099Sjoerg
191212099Sjoerg}
191312099Sjoerg
191412099Sjoerg/*
191512099Sjoerg * Copies informations about usage into a new symbol table entry of
191612099Sjoerg * the same symbol.
191712099Sjoerg */
191812099Sjoergvoid
191912099Sjoergcpuinfo(sym, rdsym)
192012099Sjoerg	sym_t	*sym, *rdsym;
192112099Sjoerg{
192212099Sjoerg	sym->s_spos = rdsym->s_spos;
192312099Sjoerg	sym->s_upos = rdsym->s_upos;
192412099Sjoerg	sym->s_set = rdsym->s_set;
192512099Sjoerg	sym->s_used = rdsym->s_used;
192612099Sjoerg}
192712099Sjoerg
192812099Sjoerg/*
192912099Sjoerg * Prints an error and returns 1 if a symbol is redeclared/redefined.
193012099Sjoerg * Otherwise returns 0 and, in some cases of minor problems, prints
193112099Sjoerg * a warning.
193212099Sjoerg */
193312099Sjoergint
193412099Sjoergisredec(dsym, warn)
193512099Sjoerg	sym_t	*dsym;
193612099Sjoerg	int	*warn;
193712099Sjoerg{
193812099Sjoerg	sym_t	*rsym;
193912099Sjoerg
194012099Sjoerg	if ((rsym = dcs->d_rdcsym)->s_scl == ENUMCON) {
194112099Sjoerg		/* redeclaration of %s */
194212099Sjoerg		error(27, dsym->s_name);
194312099Sjoerg		prevdecl(-1, rsym);
194412099Sjoerg		return (1);
194512099Sjoerg	}
194612099Sjoerg	if (rsym->s_scl == TYPEDEF) {
194712099Sjoerg		/* typedef redeclared: %s */
194812099Sjoerg		error(89, dsym->s_name);
194912099Sjoerg		prevdecl(-1, rsym);
195012099Sjoerg		return (1);
195112099Sjoerg	}
195212099Sjoerg	if (dsym->s_scl == TYPEDEF) {
195312099Sjoerg		/* redeclaration of %s */
195412099Sjoerg		error(27, dsym->s_name);
195512099Sjoerg		prevdecl(-1, rsym);
195612099Sjoerg		return (1);
195712099Sjoerg	}
195812099Sjoerg	if (rsym->s_def == DEF && dsym->s_def == DEF) {
195912099Sjoerg		/* redefinition of %s */
196012099Sjoerg		error(28, dsym->s_name);
196112099Sjoerg		prevdecl(-1, rsym);
196212099Sjoerg		return(1);
196312099Sjoerg	}
196412099Sjoerg	if (!eqtype(rsym->s_type, dsym->s_type, 0, 0, warn)) {
196512099Sjoerg		/* redeclaration of %s */
196612099Sjoerg		error(27, dsym->s_name);
196712099Sjoerg		prevdecl(-1, rsym);
196812099Sjoerg		return(1);
196912099Sjoerg	}
197012099Sjoerg	if (rsym->s_scl == EXTERN && dsym->s_scl == EXTERN)
197112099Sjoerg		return(0);
197212099Sjoerg	if (rsym->s_scl == STATIC && dsym->s_scl == STATIC)
197312099Sjoerg		return(0);
197412099Sjoerg	if (rsym->s_scl == STATIC && dsym->s_def == DECL)
197512099Sjoerg		return(0);
197612099Sjoerg	if (rsym->s_scl == EXTERN && rsym->s_def == DEF) {
197712099Sjoerg		/*
197812099Sjoerg		 * All cases except "int a = 1; static int a;" are catched
197912099Sjoerg		 * above with or without a warning
198012099Sjoerg		 */
198112099Sjoerg		/* redeclaration of %s */
198212099Sjoerg		error(27, dsym->s_name);
198312099Sjoerg		prevdecl(-1, rsym);
198412099Sjoerg		return(1);
198512099Sjoerg	}
198612099Sjoerg	if (rsym->s_scl == EXTERN) {
198712099Sjoerg		/* previously declared extern, becomes static: %s */
198812099Sjoerg		warning(29, dsym->s_name);
198912099Sjoerg		prevdecl(-1, rsym);
199012099Sjoerg		return(0);
199112099Sjoerg	}
199212099Sjoerg	/*
199312099Sjoerg	 * Now its on of:
199412099Sjoerg	 * "static a; int a;", "static a; int a = 1;", "static a = 1; int a;"
199512099Sjoerg	 */
199612099Sjoerg	/* redeclaration of %s; ANSI C requires "static" */
199712099Sjoerg	if (sflag) {
199812099Sjoerg		warning(30, dsym->s_name);
199912099Sjoerg		prevdecl(-1, rsym);
200012099Sjoerg	}
200112099Sjoerg	dsym->s_scl = STATIC;
200212099Sjoerg	return (0);
200312099Sjoerg}
200412099Sjoerg
200512099Sjoerg/*
200612099Sjoerg * Checks if two types are compatible. Returns 0 if not, otherwise 1.
200712099Sjoerg *
200812099Sjoerg * ignqual	ignore qualifiers of type; used for function params
200975697Sasmodai * promot	promote left type; used for comparison of params of
201012099Sjoerg *		old style function definitions with params of prototypes.
201112099Sjoerg * *warn	set to 1 if an old style function declaration is not
201212099Sjoerg *		compatible with a prototype
201312099Sjoerg */
201412099Sjoergint
201512099Sjoergeqtype(tp1, tp2, ignqual, promot, warn)
201612099Sjoerg	type_t	*tp1, *tp2;
201712099Sjoerg	int	ignqual, promot, *warn;
201812099Sjoerg{
201912099Sjoerg	tspec_t	t;
202012099Sjoerg
202112099Sjoerg	while (tp1 != NULL && tp2 != NULL) {
202212099Sjoerg
202312099Sjoerg		t = tp1->t_tspec;
202412099Sjoerg		if (promot) {
202512099Sjoerg			if (t == FLOAT) {
202612099Sjoerg				t = DOUBLE;
202712099Sjoerg			} else if (t == CHAR || t == SCHAR) {
202812099Sjoerg				t = INT;
202912099Sjoerg			} else if (t == UCHAR) {
203012099Sjoerg				t = tflag ? UINT : INT;
203112099Sjoerg			} else if (t == SHORT) {
203212099Sjoerg				t = INT;
203312099Sjoerg			} else if (t == USHORT) {
203412099Sjoerg				/* CONSTCOND */
203512099Sjoerg				t = INT_MAX < USHRT_MAX || tflag ? UINT : INT;
203612099Sjoerg			}
203712099Sjoerg		}
203812099Sjoerg
203912099Sjoerg		if (t != tp2->t_tspec)
204012099Sjoerg			return (0);
204112099Sjoerg
204212099Sjoerg		if (tp1->t_const != tp2->t_const && !ignqual && !tflag)
204312099Sjoerg			return (0);
204412099Sjoerg
204512099Sjoerg		if (tp1->t_volatile != tp2->t_volatile && !ignqual && !tflag)
204612099Sjoerg			return (0);
204712099Sjoerg
204812099Sjoerg		if (t == STRUCT || t == UNION)
204912099Sjoerg			return (tp1->t_str == tp2->t_str);
205012099Sjoerg
205112099Sjoerg		if (t == ARRAY && tp1->t_dim != tp2->t_dim) {
205212099Sjoerg			if (tp1->t_dim != 0 && tp2->t_dim != 0)
205312099Sjoerg				return (0);
205412099Sjoerg		}
205512099Sjoerg
205612099Sjoerg		/* dont check prototypes for traditional */
205712099Sjoerg		if (t == FUNC && !tflag) {
205812099Sjoerg			if (tp1->t_proto && tp2->t_proto) {
205912099Sjoerg				if (!eqargs(tp1, tp2, warn))
206012099Sjoerg					return (0);
206112099Sjoerg			} else if (tp1->t_proto) {
206212099Sjoerg				if (!mnoarg(tp1, warn))
206312099Sjoerg					return (0);
206412099Sjoerg			} else if (tp2->t_proto) {
206512099Sjoerg				if (!mnoarg(tp2, warn))
206612099Sjoerg					return (0);
206712099Sjoerg			}
206812099Sjoerg		}
206912099Sjoerg
207012099Sjoerg		tp1 = tp1->t_subt;
207112099Sjoerg		tp2 = tp2->t_subt;
207212099Sjoerg		ignqual = promot = 0;
207312099Sjoerg
207412099Sjoerg	}
207512099Sjoerg
207612099Sjoerg	return (tp1 == tp2);
207712099Sjoerg}
207812099Sjoerg
207912099Sjoerg/*
208012099Sjoerg * Compares the parameter types of two prototypes.
208112099Sjoerg */
208212099Sjoergstatic int
208312099Sjoergeqargs(tp1, tp2, warn)
208412099Sjoerg	type_t	*tp1, *tp2;
208512099Sjoerg	int	*warn;
208612099Sjoerg{
208712099Sjoerg	sym_t	*a1, *a2;
208812099Sjoerg
208912099Sjoerg	if (tp1->t_vararg != tp2->t_vararg)
209012099Sjoerg		return (0);
209112099Sjoerg
209212099Sjoerg	a1 = tp1->t_args;
209312099Sjoerg	a2 = tp2->t_args;
209412099Sjoerg
209512099Sjoerg	while (a1 != NULL && a2 != NULL) {
209612099Sjoerg
209712099Sjoerg		if (eqtype(a1->s_type, a2->s_type, 1, 0, warn) == 0)
209812099Sjoerg			return (0);
209912099Sjoerg
210012099Sjoerg		a1 = a1->s_nxt;
210112099Sjoerg		a2 = a2->s_nxt;
210212099Sjoerg
210312099Sjoerg	}
210412099Sjoerg
210512099Sjoerg	return (a1 == a2);
210612099Sjoerg}
210712099Sjoerg
210812099Sjoerg/*
210912099Sjoerg * mnoarg() (matches functions with no argument type information)
211012099Sjoerg * returns 1 if all parameters of a prototype are compatible with
211112099Sjoerg * and old style function declaration.
211212099Sjoerg * This is the case if following conditions are met:
211312099Sjoerg *	1. the prototype must have a fixed number of parameters
211412099Sjoerg *	2. no parameter is of type float
211512099Sjoerg *	3. no parameter is converted to another type if integer promotion
211612099Sjoerg *	   is applied on it
211712099Sjoerg */
211812099Sjoergstatic int
211912099Sjoergmnoarg(tp, warn)
212012099Sjoerg	type_t	*tp;
212112099Sjoerg	int	*warn;
212212099Sjoerg{
212312099Sjoerg	sym_t	*arg;
212412099Sjoerg	tspec_t	t;
212512099Sjoerg
212612099Sjoerg	if (tp->t_vararg) {
212712099Sjoerg		if (warn != NULL)
212812099Sjoerg			*warn = 1;
212912099Sjoerg	}
213012099Sjoerg	for (arg = tp->t_args; arg != NULL; arg = arg->s_nxt) {
213112099Sjoerg		if ((t = arg->s_type->t_tspec) == FLOAT ||
213212099Sjoerg		    t == CHAR || t == SCHAR || t == UCHAR ||
213312099Sjoerg		    t == SHORT || t == USHORT) {
213412099Sjoerg			if (warn != NULL)
213512099Sjoerg				*warn = 1;
213612099Sjoerg		}
213712099Sjoerg	}
213812099Sjoerg	return (1);
213912099Sjoerg}
214012099Sjoerg
214112099Sjoerg/*
214212099Sjoerg * Compares a prototype declaration with the remembered arguments of
214312099Sjoerg * a previous old style function definition.
214412099Sjoerg */
214512099Sjoergstatic int
214612099Sjoergchkosdef(rdsym, dsym)
214712099Sjoerg	sym_t	*rdsym, *dsym;
214812099Sjoerg{
214912099Sjoerg	sym_t	*args, *pargs, *arg, *parg;
215012099Sjoerg	int	narg, nparg, n;
215112099Sjoerg	int	warn, msg;
215212099Sjoerg
215312099Sjoerg	args = rdsym->s_args;
215412099Sjoerg	pargs = dsym->s_type->t_args;
215512099Sjoerg
215612099Sjoerg	msg = 0;
215712099Sjoerg
215812099Sjoerg	narg = nparg = 0;
215912099Sjoerg	for (arg = args; arg != NULL; arg = arg->s_nxt)
216012099Sjoerg		narg++;
216112099Sjoerg	for (parg = pargs; parg != NULL; parg = parg->s_nxt)
216212099Sjoerg		nparg++;
216312099Sjoerg	if (narg != nparg) {
216412099Sjoerg		/* prototype does not match old-style definition */
216512099Sjoerg		error(63);
216612099Sjoerg		msg = 1;
216712099Sjoerg		goto end;
216812099Sjoerg	}
216912099Sjoerg
217012099Sjoerg	arg = args;
217112099Sjoerg	parg = pargs;
217212099Sjoerg	n = 1;
217312099Sjoerg	while (narg--) {
217412099Sjoerg		warn = 0;
217512099Sjoerg		/*
217612099Sjoerg		 * If it does not match due to promotion and sflag is
217712099Sjoerg		 * not set we print only a warning.
217812099Sjoerg		 */
217912099Sjoerg		if (!eqtype(arg->s_type, parg->s_type, 1, 1, &warn) || warn) {
218012099Sjoerg			/* prototype does not match old-style def., arg #%d */
218112099Sjoerg			error(299, n);
218212099Sjoerg			msg = 1;
218312099Sjoerg		}
218412099Sjoerg		arg = arg->s_nxt;
218512099Sjoerg		parg = parg->s_nxt;
218612099Sjoerg		n++;
218712099Sjoerg	}
218812099Sjoerg
218912099Sjoerg end:
219012099Sjoerg	if (msg)
219112099Sjoerg		/* old style definition */
219212099Sjoerg		prevdecl(300, rdsym);
219312099Sjoerg
219412099Sjoerg	return (msg);
219512099Sjoerg}
219612099Sjoerg
219712099Sjoerg/*
219812099Sjoerg * Complets a type by copying the dimension and prototype information
219912099Sjoerg * from a second compatible type.
220012099Sjoerg *
220112099Sjoerg * Following lines are legal:
220212099Sjoerg *  "typedef a[]; a b; a b[10]; a c; a c[20];"
220312099Sjoerg *  "typedef ft(); ft f; f(int); ft g; g(long);"
220412099Sjoerg * This means that, if a type is completed, the type structure must
220512099Sjoerg * be duplicated.
220612099Sjoerg */
220712099Sjoergvoid
220812099Sjoergcompltyp(dsym, ssym)
220912099Sjoerg	sym_t	*dsym, *ssym;
221012099Sjoerg{
221112099Sjoerg	type_t	**dstp, *src;
221212099Sjoerg	type_t	*dst;
221312099Sjoerg
221412099Sjoerg	dstp = &dsym->s_type;
221512099Sjoerg	src = ssym->s_type;
221612099Sjoerg
221712099Sjoerg	while ((dst = *dstp) != NULL) {
221812099Sjoerg		if (src == NULL || dst->t_tspec != src->t_tspec)
221912099Sjoerg			lerror("compltyp() 1");
222012099Sjoerg		if (dst->t_tspec == ARRAY) {
222112099Sjoerg			if (dst->t_dim == 0 && src->t_dim != 0) {
222212099Sjoerg				*dstp = dst = duptyp(dst);
222312099Sjoerg				dst->t_dim = src->t_dim;
222412099Sjoerg				/* now a complete Typ */
222512099Sjoerg				setcompl(dst, 0);
222612099Sjoerg			}
222712099Sjoerg		} else if (dst->t_tspec == FUNC) {
222812099Sjoerg			if (!dst->t_proto && src->t_proto) {
222912099Sjoerg				*dstp = dst = duptyp(dst);
223012099Sjoerg				dst->t_proto = 1;
223112099Sjoerg				dst->t_args = src->t_args;
223212099Sjoerg			}
223312099Sjoerg		}
223412099Sjoerg		dstp = &dst->t_subt;
223512099Sjoerg		src = src->t_subt;
223612099Sjoerg	}
223712099Sjoerg}
223812099Sjoerg
223912099Sjoerg/*
224012099Sjoerg * Completes the declaration of a single argument.
224112099Sjoerg */
224212099Sjoergsym_t *
224312099Sjoergdecl1arg(sym, initflg)
224412099Sjoerg	sym_t	*sym;
224512099Sjoerg	int	initflg;
224612099Sjoerg{
224712099Sjoerg	tspec_t	t;
224812099Sjoerg
224912099Sjoerg	chkfdef(sym, 1);
225012099Sjoerg
225112099Sjoerg	chktyp(sym);
225212099Sjoerg
225312099Sjoerg	if (dcs->d_rdcsym != NULL && dcs->d_rdcsym->s_blklev == blklev) {
225412099Sjoerg		/* redeclaration of formal parameter %s */
225512099Sjoerg		error(237, sym->s_name);
225612099Sjoerg		rmsym(dcs->d_rdcsym);
225712099Sjoerg		sym->s_arg = 1;
225812099Sjoerg	}
225912099Sjoerg
226012099Sjoerg	if (!sym->s_arg) {
226112099Sjoerg		/* declared argument %s is missing */
226212099Sjoerg		error(53, sym->s_name);
226312099Sjoerg		sym->s_arg = 1;
226412099Sjoerg	}
226512099Sjoerg
226612099Sjoerg	if (initflg) {
226712099Sjoerg		/* cannot initialize parameter: %s */
226812099Sjoerg		error(52, sym->s_name);
226912099Sjoerg		initerr = 1;
227012099Sjoerg	}
227112099Sjoerg
227212099Sjoerg	if ((t = sym->s_type->t_tspec) == ARRAY) {
227312099Sjoerg		sym->s_type = incref(sym->s_type->t_subt, PTR);
227412099Sjoerg	} else if (t == FUNC) {
227512099Sjoerg		if (tflag)
227612099Sjoerg			/* a function is declared as an argument: %s */
227712099Sjoerg			warning(50, sym->s_name);
227812099Sjoerg		sym->s_type = incref(sym->s_type, PTR);
227912099Sjoerg	} else if (t == FLOAT) {
228012099Sjoerg		if (tflag)
228112099Sjoerg			sym->s_type = gettyp(DOUBLE);
228212099Sjoerg	}
228312099Sjoerg
228412099Sjoerg	if (dcs->d_inline)
228512099Sjoerg		/* argument declared inline: %s */
228612099Sjoerg		warning(269, sym->s_name);
228712099Sjoerg
228812099Sjoerg	/*
228912099Sjoerg	 * Arguments must have complete types. lengths() prints the needed
229012099Sjoerg	 * error messages (null dimension is impossible because arrays are
229112099Sjoerg	 * converted to pointers).
229212099Sjoerg	 */
229312099Sjoerg	if (sym->s_type->t_tspec != VOID)
229412099Sjoerg		(void)length(sym->s_type, sym->s_name);
229512099Sjoerg
229612099Sjoerg	setsflg(sym);
229712099Sjoerg
229812099Sjoerg	return (sym);
229912099Sjoerg}
230012099Sjoerg
230112099Sjoerg/*
230212099Sjoerg * Does some checks for lint directives which apply to functions.
230312099Sjoerg * Processes arguments in old style function definitions which default
230412099Sjoerg * to int.
230512099Sjoerg * Checks compatiblility of old style function definition with previous
230612099Sjoerg * prototype.
230712099Sjoerg */
230812099Sjoergvoid
230912099Sjoergcluparg()
231012099Sjoerg{
231112099Sjoerg	sym_t	*args, *arg, *pargs, *parg;
231212099Sjoerg	int	narg, nparg, n, msg;
231312099Sjoerg	tspec_t	t;
231412099Sjoerg
231512099Sjoerg	args = funcsym->s_args;
231612099Sjoerg	pargs = funcsym->s_type->t_args;
231712099Sjoerg
231812099Sjoerg	/* check for illegal combinations of lint directives */
231912099Sjoerg	if (prflstrg != -1 && scflstrg != -1) {
232012099Sjoerg		/* can't be used together: ** PRINTFLIKE ** ** SCANFLIKE ** */
232112099Sjoerg		warning(289);
232212099Sjoerg		prflstrg = scflstrg = -1;
232312099Sjoerg	}
232412099Sjoerg	if (nvararg != -1 && (prflstrg != -1 || scflstrg != -1)) {
232512099Sjoerg		/* dubious use of ** VARARGS ** with ** %s ** */
232612099Sjoerg		warning(288, prflstrg != -1 ? "PRINTFLIKE" : "SCANFLIKE");
232712099Sjoerg		nvararg = -1;
232812099Sjoerg	}
232912099Sjoerg
233012099Sjoerg	/*
233112099Sjoerg	 * check if the argument of a lint directive is compatible with the
233212099Sjoerg	 * number of arguments.
233312099Sjoerg	 */
233412099Sjoerg	narg = 0;
233512099Sjoerg	for (arg = dcs->d_fargs; arg != NULL; arg = arg->s_nxt)
233612099Sjoerg		narg++;
233712099Sjoerg	if (nargusg > narg) {
233812099Sjoerg		/* argument number mismatch with directive: ** %s ** */
233912099Sjoerg		warning(283, "ARGSUSED");
234012099Sjoerg		nargusg = 0;
234112099Sjoerg	}
234212099Sjoerg	if (nvararg > narg) {
234312099Sjoerg		/* argument number mismatch with directive: ** %s ** */
234412099Sjoerg		warning(283, "VARARGS");
234512099Sjoerg		nvararg = 0;
234612099Sjoerg	}
234712099Sjoerg	if (prflstrg > narg) {
234812099Sjoerg		/* argument number mismatch with directive: ** %s ** */
234912099Sjoerg		warning(283, "PRINTFLIKE");
235012099Sjoerg		prflstrg = -1;
235112099Sjoerg	} else if (prflstrg == 0) {
235212099Sjoerg		prflstrg = -1;
235312099Sjoerg	}
235412099Sjoerg	if (scflstrg > narg) {
235512099Sjoerg		/* argument number mismatch with directive: ** %s ** */
235612099Sjoerg		warning(283, "SCANFLIKE");
235712099Sjoerg		scflstrg = -1;
235812099Sjoerg	} else if (scflstrg == 0) {
235912099Sjoerg		scflstrg = -1;
236012099Sjoerg	}
236112099Sjoerg	if (prflstrg != -1 || scflstrg != -1) {
236212099Sjoerg		narg = prflstrg != -1 ? prflstrg : scflstrg;
236312099Sjoerg		arg = dcs->d_fargs;
236412099Sjoerg		for (n = 1; n < narg; n++)
236512099Sjoerg			arg = arg->s_nxt;
236612099Sjoerg		if (arg->s_type->t_tspec != PTR ||
236712099Sjoerg		    ((t = arg->s_type->t_subt->t_tspec) != CHAR &&
236812099Sjoerg		     t != UCHAR && t != SCHAR)) {
236912099Sjoerg			/* arg. %d must be 'char *' for PRINTFLIKE/SCANFLIKE */
237012099Sjoerg			warning(293, narg);
237112099Sjoerg			prflstrg = scflstrg = -1;
237212099Sjoerg		}
237312099Sjoerg	}
237412099Sjoerg
237512099Sjoerg	/*
237612099Sjoerg	 * print a warning for each argument off an old style function
237712099Sjoerg	 * definition which defaults to int
237812099Sjoerg	 */
237912099Sjoerg	for (arg = args; arg != NULL; arg = arg->s_nxt) {
238012099Sjoerg		if (arg->s_defarg) {
238112099Sjoerg			/* argument type defaults to int: %s */
238212099Sjoerg			warning(32, arg->s_name);
238312099Sjoerg			arg->s_defarg = 0;
238412099Sjoerg			setsflg(arg);
238512099Sjoerg		}
238612099Sjoerg	}
238712099Sjoerg
238812099Sjoerg	/*
238912099Sjoerg	 * If this is an old style function definition and a prototyp
239012099Sjoerg	 * exists, compare the types of arguments.
239112099Sjoerg	 */
239212099Sjoerg	if (funcsym->s_osdef && funcsym->s_type->t_proto) {
239312099Sjoerg		/*
239412099Sjoerg		 * If the number of arguments does not macht, we need not
239512099Sjoerg		 * continue.
239612099Sjoerg		 */
239712099Sjoerg		narg = nparg = 0;
239812099Sjoerg		msg = 0;
239912099Sjoerg		for (parg = pargs; parg != NULL; parg = parg->s_nxt)
240012099Sjoerg			nparg++;
240112099Sjoerg		for (arg = args; arg != NULL; arg = arg->s_nxt)
240212099Sjoerg			narg++;
240312099Sjoerg		if (narg != nparg) {
240412099Sjoerg			/* parameter mismatch: %d declared, %d defined */
240512099Sjoerg			error(51, nparg, narg);
240612099Sjoerg			msg = 1;
240712099Sjoerg		} else {
240812099Sjoerg			parg = pargs;
240912099Sjoerg			arg = args;
241012099Sjoerg			while (narg--) {
241112099Sjoerg				msg |= chkptdecl(arg, parg);
241212099Sjoerg				parg = parg->s_nxt;
241312099Sjoerg				arg = arg->s_nxt;
241412099Sjoerg			}
241512099Sjoerg		}
241612099Sjoerg		if (msg)
241712099Sjoerg			/* prototype declaration */
241812099Sjoerg			prevdecl(285, dcs->d_rdcsym);
241912099Sjoerg
242012099Sjoerg		/* from now the prototype is valid */
242112099Sjoerg		funcsym->s_osdef = 0;
242212099Sjoerg		funcsym->s_args = NULL;
242312099Sjoerg
242412099Sjoerg	}
242512099Sjoerg
242612099Sjoerg}
242712099Sjoerg
242812099Sjoerg/*
242912099Sjoerg * Checks compatibility of an old style function definition with a previous
243012099Sjoerg * prototype declaration.
243112099Sjoerg * Returns 1 if the position of the previous declaration should be reported.
243212099Sjoerg */
243312099Sjoergstatic int
243412099Sjoergchkptdecl(arg, parg)
243512099Sjoerg	sym_t	*arg, *parg;
243612099Sjoerg{
243712099Sjoerg	type_t	*tp, *ptp;
243812099Sjoerg	int	warn, msg;
243912099Sjoerg
244012099Sjoerg	tp = arg->s_type;
244112099Sjoerg	ptp = parg->s_type;
244212099Sjoerg
244312099Sjoerg	msg = 0;
244412099Sjoerg	warn = 0;
244512099Sjoerg
244612099Sjoerg	if (!eqtype(tp, ptp, 1, 1, &warn)) {
244712099Sjoerg		if (eqtype(tp, ptp, 1, 0, &warn)) {
244812099Sjoerg			/* type does not match prototype: %s */
244912099Sjoerg			msg = gnuism(58, arg->s_name);
245012099Sjoerg		} else {
245112099Sjoerg			/* type does not match prototype: %s */
245212099Sjoerg			error(58, arg->s_name);
245312099Sjoerg			msg = 1;
245412099Sjoerg		}
245512099Sjoerg	} else if (warn) {
245612099Sjoerg		/* type does not match prototype: %s */
245712099Sjoerg		(*(sflag ? error : warning))(58, arg->s_name);
245812099Sjoerg		msg = 1;
245912099Sjoerg	}
246012099Sjoerg
246112099Sjoerg	return (msg);
246212099Sjoerg}
246312099Sjoerg
246412099Sjoerg/*
246512099Sjoerg * Completes a single local declaration/definition.
246612099Sjoerg */
246712099Sjoergvoid
246812099Sjoergdecl1loc(dsym, initflg)
246912099Sjoerg	sym_t	*dsym;
247012099Sjoerg	int	initflg;
247112099Sjoerg{
247212099Sjoerg	/* Correct a mistake done in dname(). */
247312099Sjoerg	if (dsym->s_type->t_tspec == FUNC) {
247412099Sjoerg		dsym->s_def = DECL;
247512099Sjoerg		if (dcs->d_scl == NOSCL)
247612099Sjoerg			dsym->s_scl = EXTERN;
247712099Sjoerg	}
247812099Sjoerg
247912099Sjoerg	if (dsym->s_type->t_tspec == FUNC) {
248012099Sjoerg		if (dsym->s_scl == STATIC) {
248112099Sjoerg			/* dubious static function at block level: %s */
248212099Sjoerg			warning(93, dsym->s_name);
248312099Sjoerg			dsym->s_scl = EXTERN;
248412099Sjoerg		} else if (dsym->s_scl != EXTERN && dsym->s_scl != TYPEDEF) {
248512099Sjoerg			/* function has illegal storage class: %s */
248612099Sjoerg			error(94, dsym->s_name);
248712099Sjoerg			dsym->s_scl = EXTERN;
248812099Sjoerg		}
248912099Sjoerg	}
249012099Sjoerg
249112099Sjoerg	/*
249212099Sjoerg	 * functions may be declared inline at local scope, although
249312099Sjoerg	 * this has no effect for a later definition of the same
249412099Sjoerg	 * function.
249512099Sjoerg	 * XXX it should have an effect if tflag is set. this would
249612099Sjoerg	 * also be the way gcc behaves.
249712099Sjoerg	 */
249812099Sjoerg	if (dcs->d_inline) {
249912099Sjoerg		if (dsym->s_type->t_tspec == FUNC) {
250012099Sjoerg			dsym->s_inline = 1;
250112099Sjoerg		} else {
250212099Sjoerg			/* variable declared inline: %s */
250312099Sjoerg			warning(268, dsym->s_name);
250412099Sjoerg		}
250512099Sjoerg	}
250612099Sjoerg
250712099Sjoerg	chkfdef(dsym, 1);
250812099Sjoerg
250912099Sjoerg	chktyp(dsym);
251012099Sjoerg
251112099Sjoerg	if (dcs->d_rdcsym != NULL && dsym->s_scl == EXTERN)
251212099Sjoerg		ledecl(dsym);
251312099Sjoerg
251412099Sjoerg	if (dsym->s_scl == EXTERN) {
251512099Sjoerg		/*
251612099Sjoerg		 * XXX wenn die statische Variable auf Ebene 0 erst
251712099Sjoerg		 * spaeter definiert wird, haben wir die Brille auf.
251812099Sjoerg		 */
251912099Sjoerg		if (dsym->s_xsym == NULL) {
252012099Sjoerg			outsym(dsym, EXTERN, dsym->s_def);
252112099Sjoerg		} else {
252212099Sjoerg			outsym(dsym, dsym->s_xsym->s_scl, dsym->s_def);
252312099Sjoerg		}
252412099Sjoerg	}
252512099Sjoerg
252612099Sjoerg	if (dcs->d_rdcsym != NULL) {
252712099Sjoerg
252812099Sjoerg		if (dcs->d_rdcsym->s_blklev == 0) {
252912099Sjoerg
253012099Sjoerg			switch (dsym->s_scl) {
253112099Sjoerg			case AUTO:
253212099Sjoerg				/* automatic hides external declaration: %s */
253312099Sjoerg				if (hflag)
253412099Sjoerg					warning(86, dsym->s_name);
253512099Sjoerg				break;
253612099Sjoerg			case STATIC:
253712099Sjoerg				/* static hides external declaration: %s */
253812099Sjoerg				if (hflag)
253912099Sjoerg					warning(87, dsym->s_name);
254012099Sjoerg				break;
254112099Sjoerg			case TYPEDEF:
254212099Sjoerg				/* typedef hides  external declaration: %s */
254312099Sjoerg				if (hflag)
254412099Sjoerg					warning(88, dsym->s_name);
254512099Sjoerg				break;
254612099Sjoerg			case EXTERN:
254712099Sjoerg				/*
254812099Sjoerg				 * Warnings and errors are printed in ledecl()
254912099Sjoerg				 */
255012099Sjoerg				break;
255112099Sjoerg			default:
255212099Sjoerg				lerror("decl1loc() 1");
255312099Sjoerg			}
255412099Sjoerg
255512099Sjoerg		} else if (dcs->d_rdcsym->s_blklev == blklev) {
255612099Sjoerg
255712099Sjoerg			/* no hflag, because its illegal! */
255812099Sjoerg			if (dcs->d_rdcsym->s_arg) {
255912099Sjoerg				/*
256012099Sjoerg				 * if !tflag, a "redeclaration of %s" error
256112099Sjoerg				 * is produced below
256212099Sjoerg				 */
256312099Sjoerg				if (tflag) {
256412099Sjoerg					if (hflag)
256512099Sjoerg						/* decl. hides parameter: %s */
256612099Sjoerg						warning(91, dsym->s_name);
256712099Sjoerg					rmsym(dcs->d_rdcsym);
256812099Sjoerg				}
256912099Sjoerg			}
257012099Sjoerg
257112099Sjoerg		} else if (dcs->d_rdcsym->s_blklev < blklev) {
257212099Sjoerg
257312099Sjoerg			if (hflag)
257412099Sjoerg				/* declaration hides earlier one: %s */
257512099Sjoerg				warning(95, dsym->s_name);
257612099Sjoerg
257712099Sjoerg		}
257812099Sjoerg
257912099Sjoerg		if (dcs->d_rdcsym->s_blklev == blklev) {
258012099Sjoerg
258112099Sjoerg			/* redeclaration of %s */
258212099Sjoerg			error(27, dsym->s_name);
258312099Sjoerg			rmsym(dcs->d_rdcsym);
258412099Sjoerg
258512099Sjoerg		}
258612099Sjoerg
258712099Sjoerg	}
258812099Sjoerg
258912099Sjoerg	if (initflg && !(initerr = chkinit(dsym))) {
259012099Sjoerg		dsym->s_def = DEF;
259112099Sjoerg		setsflg(dsym);
259212099Sjoerg	}
259312099Sjoerg
259412099Sjoerg	if (dsym->s_scl == TYPEDEF) {
259512099Sjoerg		dsym->s_type = duptyp(dsym->s_type);
259612099Sjoerg		dsym->s_type->t_typedef = 1;
259712099Sjoerg		settdsym(dsym->s_type, dsym);
259812099Sjoerg	}
259912099Sjoerg
260012099Sjoerg	/*
260112099Sjoerg	 * Before we can check the size we must wait for a initialisation
260212099Sjoerg	 * which may follow.
260312099Sjoerg	 */
260412099Sjoerg}
260512099Sjoerg
260612099Sjoerg/*
260712099Sjoerg * Processes (re)declarations of external Symbols inside blocks.
260812099Sjoerg */
260912099Sjoergstatic void
261012099Sjoergledecl(dsym)
261112099Sjoerg	sym_t	*dsym;
261212099Sjoerg{
261312099Sjoerg	int	eqt, warn;
261412099Sjoerg	sym_t	*esym;
261512099Sjoerg
261612099Sjoerg	/* look for a symbol with the same name */
261712099Sjoerg	esym = dcs->d_rdcsym;
261812099Sjoerg	while (esym != NULL && esym->s_blklev != 0) {
261912099Sjoerg		while ((esym = esym->s_link) != NULL) {
262012099Sjoerg			if (esym->s_kind != FVFT)
262112099Sjoerg				continue;
262212099Sjoerg			if (strcmp(dsym->s_name, esym->s_name) == 0)
262312099Sjoerg				break;
262412099Sjoerg		}
262512099Sjoerg	}
262612099Sjoerg	if (esym == NULL)
262712099Sjoerg		return;
262812099Sjoerg	if (esym->s_scl != EXTERN && esym->s_scl != STATIC) {
262912099Sjoerg		/* gcc accepts this without a warning, pcc prints an error. */
263012099Sjoerg		/* redeclaration of %s */
263112099Sjoerg		warning(27, dsym->s_name);
263212099Sjoerg		prevdecl(-1, esym);
263312099Sjoerg		return;
263412099Sjoerg	}
263512099Sjoerg
263612099Sjoerg	warn = 0;
263712099Sjoerg	eqt = eqtype(esym->s_type, dsym->s_type, 0, 0, &warn);
263812099Sjoerg
263912099Sjoerg	if (!eqt || warn) {
264012099Sjoerg		if (esym->s_scl == EXTERN) {
264112099Sjoerg			/* inconsistent redeclaration of extern: %s */
264212099Sjoerg			warning(90, dsym->s_name);
264312099Sjoerg			prevdecl(-1, esym);
264412099Sjoerg		} else {
264512099Sjoerg			/* inconsistent redeclaration of static: %s */
264612099Sjoerg			warning(92, dsym->s_name);
264712099Sjoerg			prevdecl(-1, esym);
264812099Sjoerg		}
264912099Sjoerg	}
265012099Sjoerg
265112099Sjoerg	if (eqt) {
265212099Sjoerg		/*
265312099Sjoerg		 * Remember the external symbol so we can update usage
265412099Sjoerg		 * information at the end of the block.
265512099Sjoerg		 */
265612099Sjoerg		dsym->s_xsym = esym;
265712099Sjoerg	}
265812099Sjoerg}
265912099Sjoerg
266012099Sjoerg/*
266112099Sjoerg * Print an error or a warning if the symbol cant be initialized due
266212099Sjoerg * to type/storage class. Returnvalue is 1 if an error has been
266312099Sjoerg * detected.
266412099Sjoerg */
266512099Sjoergstatic int
266612099Sjoergchkinit(sym)
266712099Sjoerg	sym_t	*sym;
266812099Sjoerg{
266912099Sjoerg	int	err;
267012099Sjoerg
267112099Sjoerg	err = 0;
267212099Sjoerg
267312099Sjoerg	if (sym->s_type->t_tspec == FUNC) {
267412099Sjoerg		/* cannot initialize function: %s */
267512099Sjoerg		error(24, sym->s_name);
267612099Sjoerg		err = 1;
267712099Sjoerg	} else if (sym->s_scl == TYPEDEF) {
267812099Sjoerg		/* cannot initialize typedef: %s */
267912099Sjoerg		error(25, sym->s_name);
268012099Sjoerg		err = 1;
268112099Sjoerg	} else if (sym->s_scl == EXTERN && sym->s_def == DECL) {
268212099Sjoerg		/* cannot initialize "extern" declaration: %s */
268312099Sjoerg		if (dcs->d_ctx == EXTERN) {
268412099Sjoerg			warning(26, sym->s_name);
268512099Sjoerg		} else {
268612099Sjoerg			error(26, sym->s_name);
268712099Sjoerg			err = 1;
268812099Sjoerg		}
268912099Sjoerg	}
269012099Sjoerg
269112099Sjoerg	return (err);
269212099Sjoerg}
269312099Sjoerg
269412099Sjoerg/*
269512099Sjoerg * Create a symbole for an abstract declaration.
269612099Sjoerg */
269712099Sjoergsym_t *
269812099Sjoerganame()
269912099Sjoerg{
270012099Sjoerg	sym_t	*sym;
270112099Sjoerg
270212099Sjoerg	if (dcs->d_ctx != ABSTRACT && dcs->d_ctx != PARG)
270312099Sjoerg		lerror("aname()");
270412099Sjoerg
270512099Sjoerg	sym = getblk(sizeof (sym_t));
270612099Sjoerg
270712099Sjoerg	sym->s_name = unnamed;
270812099Sjoerg	sym->s_def = DEF;
270912099Sjoerg	sym->s_scl = ABSTRACT;
271012099Sjoerg	sym->s_blklev = -1;
271112099Sjoerg
271212099Sjoerg	if (dcs->d_ctx == PARG)
271312099Sjoerg		sym->s_arg = 1;
271412099Sjoerg
271512099Sjoerg	sym->s_type = dcs->d_type;
271612099Sjoerg	dcs->d_rdcsym = NULL;
271712099Sjoerg	dcs->d_vararg = 0;
271812099Sjoerg
271912099Sjoerg	return (sym);
272012099Sjoerg}
272112099Sjoerg
272212099Sjoerg/*
272312099Sjoerg * Removes anything which has nothing to do on global level.
272412099Sjoerg */
272512099Sjoergvoid
272612099Sjoergglobclup()
272712099Sjoerg{
272812099Sjoerg	while (dcs->d_nxt != NULL)
272912099Sjoerg		popdecl();
273012099Sjoerg
273112099Sjoerg	cleanup();
273212099Sjoerg	blklev = 0;
273312099Sjoerg	mblklev = 0;
273412099Sjoerg
273512099Sjoerg	/*
273612099Sjoerg	 * remove all informations about pending lint directives without
273712099Sjoerg	 * warnings.
273812099Sjoerg	 */
273912099Sjoerg	glclup(1);
274012099Sjoerg}
274112099Sjoerg
274212099Sjoerg/*
274312099Sjoerg * Process an abstract type declaration
274412099Sjoerg */
274512099Sjoergsym_t *
274612099Sjoergdecl1abs(sym)
274712099Sjoerg	sym_t	*sym;
274812099Sjoerg{
274912099Sjoerg	chkfdef(sym, 1);
275012099Sjoerg	chktyp(sym);
275112099Sjoerg	return (sym);
275212099Sjoerg}
275312099Sjoerg
275412099Sjoerg/*
275512099Sjoerg * Checks size after declarations of variables and their initialisation.
275612099Sjoerg */
275712099Sjoergvoid
275812099Sjoergchksz(dsym)
275912099Sjoerg	sym_t	*dsym;
276012099Sjoerg{
276112099Sjoerg	/*
276212099Sjoerg	 * check size only for symbols which are defined and no function and
276312099Sjoerg	 * not typedef name
276412099Sjoerg	 */
276512099Sjoerg	if (dsym->s_def != DEF)
276612099Sjoerg		return;
276712099Sjoerg	if (dsym->s_scl == TYPEDEF)
276812099Sjoerg		return;
276912099Sjoerg	if (dsym->s_type->t_tspec == FUNC)
277012099Sjoerg		return;
277112099Sjoerg
277212099Sjoerg	if (length(dsym->s_type, dsym->s_name) == 0 &&
277312099Sjoerg	    dsym->s_type->t_tspec == ARRAY && dsym->s_type->t_dim == 0) {
277412099Sjoerg		/* empty array declaration: %s */
277512099Sjoerg		if (tflag) {
277612099Sjoerg			warning(190, dsym->s_name);
277712099Sjoerg		} else {
277812099Sjoerg			error(190, dsym->s_name);
277912099Sjoerg		}
278012099Sjoerg	}
278112099Sjoerg}
278212099Sjoerg
278312099Sjoerg/*
278412099Sjoerg * Mark an object as set if it is not already
278512099Sjoerg */
278612099Sjoergvoid
278712099Sjoergsetsflg(sym)
278812099Sjoerg	sym_t	*sym;
278912099Sjoerg{
279012099Sjoerg	if (!sym->s_set) {
279112099Sjoerg		sym->s_set = 1;
279212099Sjoerg		STRUCT_ASSIGN(sym->s_spos, curr_pos);
279312099Sjoerg	}
279412099Sjoerg}
279512099Sjoerg
279612099Sjoerg/*
279712099Sjoerg * Mark an object as used if it is not already
279812099Sjoerg */
279912099Sjoergvoid
280012099Sjoergsetuflg(sym, fcall, szof)
280112099Sjoerg	sym_t	*sym;
280212099Sjoerg	int	fcall, szof;
280312099Sjoerg{
280412099Sjoerg	if (!sym->s_used) {
280512099Sjoerg		sym->s_used = 1;
280612099Sjoerg		STRUCT_ASSIGN(sym->s_upos, curr_pos);
280712099Sjoerg	}
280812099Sjoerg	/*
280912099Sjoerg	 * for function calls another record is written
281012099Sjoerg	 *
281112099Sjoerg	 * XXX Should symbols used in sizeof() treated as used or not?
281212099Sjoerg	 * Probably not, because there is no sense to declare an
281312099Sjoerg	 * external variable only to get their size.
281412099Sjoerg	 */
281512099Sjoerg	if (!fcall && !szof && sym->s_kind == FVFT && sym->s_scl == EXTERN)
281612099Sjoerg		outusg(sym);
281712099Sjoerg}
281812099Sjoerg
281912099Sjoerg/*
282012099Sjoerg * Prints warnings for a list of variables and labels (concatenated
282112099Sjoerg * with s_dlnxt) if these are not used or only set.
282212099Sjoerg */
282312099Sjoergvoid
282412099Sjoergchkusage(di)
282512099Sjoerg	dinfo_t	*di;
282612099Sjoerg{
282712099Sjoerg	sym_t	*sym;
282812099Sjoerg	int	mknowarn;
282912099Sjoerg
283012099Sjoerg	/* for this warnings LINTED has no effect */
283112099Sjoerg	mknowarn = nowarn;
283212099Sjoerg	nowarn = 0;
283312099Sjoerg
283412099Sjoerg	for (sym = di->d_dlsyms; sym != NULL; sym = sym->s_dlnxt)
283512099Sjoerg		chkusg1(di->d_asm, sym);
283612099Sjoerg
283712099Sjoerg	nowarn = mknowarn;
283812099Sjoerg}
283912099Sjoerg
284012099Sjoerg/*
284112099Sjoerg * Prints a warning for a single variable or label if it is not used or
284212099Sjoerg * only set.
284312099Sjoerg */
284412099Sjoergvoid
284512099Sjoergchkusg1(novar, sym)
284612099Sjoerg	int	novar;
284712099Sjoerg	sym_t	*sym;
284812099Sjoerg{
284912099Sjoerg	pos_t	cpos;
285012099Sjoerg
285112099Sjoerg	if (sym->s_blklev == -1)
285212099Sjoerg		return;
285312099Sjoerg
285412099Sjoerg	STRUCT_ASSIGN(cpos, curr_pos);
285512099Sjoerg
285612099Sjoerg	if (sym->s_kind == FVFT) {
285712099Sjoerg		if (sym->s_arg) {
285812099Sjoerg			chkausg(novar, sym);
285912099Sjoerg		} else {
286012099Sjoerg			chkvusg(novar, sym);
286112099Sjoerg		}
286212099Sjoerg	} else if (sym->s_kind == FLAB) {
286312099Sjoerg		chklusg(sym);
286412099Sjoerg	} else if (sym->s_kind == FTAG) {
286512099Sjoerg		chktusg(sym);
286612099Sjoerg	}
286712099Sjoerg
286812099Sjoerg	STRUCT_ASSIGN(curr_pos, cpos);
286912099Sjoerg}
287012099Sjoerg
287112099Sjoergstatic void
287212099Sjoergchkausg(novar, arg)
287312099Sjoerg	int	novar;
287412099Sjoerg	sym_t	*arg;
287512099Sjoerg{
287612099Sjoerg	if (!arg->s_set)
287712099Sjoerg		lerror("chkausg() 1");
287812099Sjoerg
287912099Sjoerg	if (novar)
288012099Sjoerg		return;
288112099Sjoerg
288212099Sjoerg	if (!arg->s_used && vflag) {
288312099Sjoerg		STRUCT_ASSIGN(curr_pos, arg->s_dpos);
288412099Sjoerg		/* argument %s unused in function %s */
288512099Sjoerg		warning(231, arg->s_name, funcsym->s_name);
288612099Sjoerg	}
288712099Sjoerg}
288812099Sjoerg
288912099Sjoergstatic void
289012099Sjoergchkvusg(novar, sym)
289112099Sjoerg	int	novar;
289212099Sjoerg	sym_t	*sym;
289312099Sjoerg{
289412099Sjoerg	scl_t	sc;
289512099Sjoerg	sym_t	*xsym;
289612099Sjoerg
289712099Sjoerg	if (blklev == 0 || sym->s_blklev == 0)
289812099Sjoerg		lerror("chkvusg() 1");
289912099Sjoerg
290012099Sjoerg	/* errors in expressions easily cause lots of these warnings */
290112099Sjoerg	if (nerr != 0)
290212099Sjoerg		return;
290312099Sjoerg
290412099Sjoerg	/*
290512099Sjoerg	 * XXX Only variables are checkd, although types should
290612099Sjoerg	 * probably also be checked
290712099Sjoerg	 */
290812099Sjoerg	if ((sc = sym->s_scl) != EXTERN && sc != STATIC &&
290912099Sjoerg	    sc != AUTO && sc != REG) {
291012099Sjoerg		return;
291112099Sjoerg	}
291212099Sjoerg
291312099Sjoerg	if (novar)
291412099Sjoerg		return;
291512099Sjoerg
291612099Sjoerg	if (sc == EXTERN) {
291712099Sjoerg		if (!sym->s_used && !sym->s_set) {
291812099Sjoerg			STRUCT_ASSIGN(curr_pos, sym->s_dpos);
291912099Sjoerg			/* %s unused in function %s */
292012099Sjoerg			warning(192, sym->s_name, funcsym->s_name);
292112099Sjoerg		}
292212099Sjoerg	} else {
292312099Sjoerg		if (sym->s_set && !sym->s_used) {
292412099Sjoerg			STRUCT_ASSIGN(curr_pos, sym->s_spos);
292512099Sjoerg			/* %s set but not used in function %s */
292612099Sjoerg			warning(191, sym->s_name, funcsym->s_name);
292712099Sjoerg		} else if (!sym->s_used) {
292812099Sjoerg			STRUCT_ASSIGN(curr_pos, sym->s_dpos);
292912099Sjoerg			/* %s unused in function %s */
293012099Sjoerg			warning(192, sym->s_name, funcsym->s_name);
293112099Sjoerg		}
293212099Sjoerg	}
293312099Sjoerg
293412099Sjoerg	if (sc == EXTERN) {
293512099Sjoerg		/*
293612099Sjoerg		 * information about usage is taken over into the symbol
293712099Sjoerg		 * tabel entry at level 0 if the symbol was locally declared
293812099Sjoerg		 * as an external symbol.
293912099Sjoerg		 *
294012099Sjoerg		 * XXX This is wrong for symbols declared static at level 0
294112099Sjoerg		 * if the usage information stems from sizeof(). This is
294212099Sjoerg		 * because symbols at level 0 only used in sizeof() are
294312099Sjoerg		 * considered to not be used.
294412099Sjoerg		 */
294512099Sjoerg		if ((xsym = sym->s_xsym) != NULL) {
294612099Sjoerg			if (sym->s_used && !xsym->s_used) {
294712099Sjoerg				xsym->s_used = 1;
294812099Sjoerg				STRUCT_ASSIGN(xsym->s_upos, sym->s_upos);
294912099Sjoerg			}
295012099Sjoerg			if (sym->s_set && !xsym->s_set) {
295112099Sjoerg				xsym->s_set = 1;
295212099Sjoerg				STRUCT_ASSIGN(xsym->s_spos, sym->s_spos);
295312099Sjoerg			}
295412099Sjoerg		}
295512099Sjoerg	}
295612099Sjoerg}
295712099Sjoerg
295812099Sjoergstatic void
295912099Sjoergchklusg(lab)
296012099Sjoerg	sym_t	*lab;
296112099Sjoerg{
296212099Sjoerg	if (blklev != 1 || lab->s_blklev != 1)
296312099Sjoerg		lerror("chklusg() 1");
296412099Sjoerg
296512099Sjoerg	if (lab->s_set && !lab->s_used) {
296612099Sjoerg		STRUCT_ASSIGN(curr_pos, lab->s_spos);
296712099Sjoerg		/* label %s unused in function %s */
296812099Sjoerg		warning(192, lab->s_name, funcsym->s_name);
296912099Sjoerg	} else if (!lab->s_set) {
297012099Sjoerg		STRUCT_ASSIGN(curr_pos, lab->s_upos);
297112099Sjoerg		/* undefined label %s */
297212099Sjoerg		warning(23, lab->s_name);
297312099Sjoerg	}
297412099Sjoerg}
297512099Sjoerg
297612099Sjoergstatic void
297712099Sjoergchktusg(sym)
297812099Sjoerg	sym_t	*sym;
297912099Sjoerg{
298012099Sjoerg	if (!incompl(sym->s_type))
298112099Sjoerg		return;
298212099Sjoerg
298312099Sjoerg	/* complain alwasy about incomplet tags declared inside blocks */
298412099Sjoerg	if (!zflag || dcs->d_ctx != EXTERN)
298512099Sjoerg		return;
298612099Sjoerg
298712099Sjoerg	STRUCT_ASSIGN(curr_pos, sym->s_dpos);
298812099Sjoerg	switch (sym->s_type->t_tspec) {
298912099Sjoerg	case STRUCT:
299012099Sjoerg		/* struct %s never defined */
299112099Sjoerg		warning(233, sym->s_name);
299212099Sjoerg		break;
299312099Sjoerg	case UNION:
299412099Sjoerg		/* union %s never defined */
299512099Sjoerg		warning(234, sym->s_name);
299612099Sjoerg		break;
299712099Sjoerg	case ENUM:
299812099Sjoerg		/* enum %s never defined */
299912099Sjoerg		warning(235, sym->s_name);
300012099Sjoerg		break;
300112099Sjoerg	default:
300212099Sjoerg		lerror("chktusg() 1");
300312099Sjoerg	}
300412099Sjoerg}
300512099Sjoerg
300612099Sjoerg/*
300712099Sjoerg * Called after the entire translation unit has been parsed.
300812099Sjoerg * Changes tentative definitions in definitions.
300912099Sjoerg * Performs some tests on global Symbols. Detected Problems are:
301012099Sjoerg * - defined variables of incomplete type
301112099Sjoerg * - constant variables which are not initialized
301212099Sjoerg * - static symbols which are never used
301312099Sjoerg */
301412099Sjoergvoid
301512099Sjoergchkglsyms()
301612099Sjoerg{
301712099Sjoerg	sym_t	*sym;
301812099Sjoerg	pos_t	cpos;
301912099Sjoerg
302012099Sjoerg	if (blklev != 0 || dcs->d_nxt != NULL)
302112099Sjoerg		norecover();
302212099Sjoerg
302312099Sjoerg	STRUCT_ASSIGN(cpos, curr_pos);
302412099Sjoerg
302512099Sjoerg	for (sym = dcs->d_dlsyms; sym != NULL; sym = sym->s_dlnxt) {
302612099Sjoerg		if (sym->s_blklev == -1)
302712099Sjoerg			continue;
302812099Sjoerg		if (sym->s_kind == FVFT) {
302912099Sjoerg			chkglvar(sym);
303012099Sjoerg		} else if (sym->s_kind == FTAG) {
303112099Sjoerg			chktusg(sym);
303212099Sjoerg		} else {
303312099Sjoerg			if (sym->s_kind != FMOS)
303412099Sjoerg				lerror("chkglsyms() 1");
303512099Sjoerg		}
303612099Sjoerg	}
303712099Sjoerg
303812099Sjoerg	STRUCT_ASSIGN(curr_pos, cpos);
303912099Sjoerg}
304012099Sjoerg
304112099Sjoergstatic void
304212099Sjoergchkglvar(sym)
304312099Sjoerg	sym_t	*sym;
304412099Sjoerg{
304512099Sjoerg	if (sym->s_scl == TYPEDEF || sym->s_scl == ENUMCON)
304612099Sjoerg		return;
304712099Sjoerg
304812099Sjoerg	if (sym->s_scl != EXTERN && sym->s_scl != STATIC)
304912099Sjoerg		lerror("chkglvar() 1");
305012099Sjoerg
305112099Sjoerg	glchksz(sym);
305212099Sjoerg
305312099Sjoerg	if (sym->s_scl == STATIC) {
305412099Sjoerg		if (sym->s_type->t_tspec == FUNC) {
305512099Sjoerg			if (sym->s_used && sym->s_def != DEF) {
305612099Sjoerg				STRUCT_ASSIGN(curr_pos, sym->s_upos);
305712099Sjoerg				/* static func. called but not def.. */
305812099Sjoerg				error(225, sym->s_name);
305912099Sjoerg			}
306012099Sjoerg		}
306112099Sjoerg		if (!sym->s_used) {
306212099Sjoerg			STRUCT_ASSIGN(curr_pos, sym->s_dpos);
306312099Sjoerg			if (sym->s_type->t_tspec == FUNC) {
306412099Sjoerg				if (sym->s_def == DEF) {
306512099Sjoerg					if (!sym->s_inline)
306612099Sjoerg						/* static function %s unused */
306712099Sjoerg						warning(236, sym->s_name);
306812099Sjoerg				} else {
306912099Sjoerg					/* static function %s decl. but ... */
307012099Sjoerg					warning(290, sym->s_name);
307112099Sjoerg				}
307212099Sjoerg			} else if (!sym->s_set) {
307312099Sjoerg				/* static variable %s unused */
307412099Sjoerg				warning(226, sym->s_name);
307512099Sjoerg			} else {
307612099Sjoerg				/* static variable %s set but not used */
307712099Sjoerg				warning(307, sym->s_name);
307812099Sjoerg			}
307912099Sjoerg		}
308012099Sjoerg		if (!tflag && sym->s_def == TDEF && sym->s_type->t_const) {
308112099Sjoerg			STRUCT_ASSIGN(curr_pos, sym->s_dpos);
308212099Sjoerg			/* const object %s should have initializer */
308312099Sjoerg			warning(227, sym->s_name);
308412099Sjoerg		}
308512099Sjoerg	}
308612099Sjoerg}
308712099Sjoerg
308812099Sjoergstatic void
308912099Sjoergglchksz(sym)
309012099Sjoerg	sym_t	*sym;
309112099Sjoerg{
309212099Sjoerg	if (sym->s_def == TDEF) {
309312099Sjoerg		if (sym->s_type->t_tspec == FUNC)
309412099Sjoerg			/*
309512099Sjoerg			 * this can happen if an syntax error occured
309612099Sjoerg			 * after a function declaration
309712099Sjoerg			 */
309812099Sjoerg			return;
309912099Sjoerg		STRUCT_ASSIGN(curr_pos, sym->s_dpos);
310012099Sjoerg		if (length(sym->s_type, sym->s_name) == 0 &&
310112099Sjoerg		    sym->s_type->t_tspec == ARRAY && sym->s_type->t_dim == 0) {
310212099Sjoerg			/* empty array declaration: %s */
310312099Sjoerg			if (tflag || (sym->s_scl == EXTERN && !sflag)) {
310412099Sjoerg				warning(190, sym->s_name);
310512099Sjoerg			} else {
310612099Sjoerg				error(190, sym->s_name);
310712099Sjoerg			}
310812099Sjoerg		}
310912099Sjoerg	}
311012099Sjoerg}
311112099Sjoerg
311212099Sjoerg/*
311312099Sjoerg * Prints information about location of previous definition/declaration.
311412099Sjoerg */
311512099Sjoergvoid
311612099Sjoergprevdecl(msg, psym)
311712099Sjoerg	int	msg;
311812099Sjoerg	sym_t	*psym;
311912099Sjoerg{
312012099Sjoerg	pos_t	cpos;
312112099Sjoerg
312212099Sjoerg	if (!rflag)
312312099Sjoerg		return;
312412099Sjoerg
312512099Sjoerg	STRUCT_ASSIGN(cpos, curr_pos);
312612099Sjoerg	STRUCT_ASSIGN(curr_pos, psym->s_dpos);
312712099Sjoerg	if (msg != -1) {
312812099Sjoerg		message(msg, psym->s_name);
312912099Sjoerg	} else if (psym->s_def == DEF || psym->s_def == TDEF) {
313012099Sjoerg		/* previous definition of %s */
313112099Sjoerg		message(261, psym->s_name);
313212099Sjoerg	} else {
313312099Sjoerg		/* previous declaration of %s */
313412099Sjoerg		message(260, psym->s_name);
313512099Sjoerg	}
313612099Sjoerg	STRUCT_ASSIGN(curr_pos, cpos);
313712099Sjoerg}
3138