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