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