decl.c revision 206424
191592Smarkm/* $NetBSD: decl.c,v 1.29 2002/01/18 21:01:39 thorpej 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)
3791592Smarkm__RCSID("$NetBSD: decl.c,v 1.29 2002/01/18 21:01:39 thorpej Exp $");
3812099Sjoerg#endif
3991592Smarkm__FBSDID("$FreeBSD: head/usr.bin/xlint/lint1/decl.c 206424 2010-04-09 15:21:11Z rdivacky $");
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 *
13012099Sjoerg * It's important do 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)
20012099Sjoerg			lerror("setcompl() 1");
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			 */
25912099Sjoerg			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' */
30012099Sjoerg			(void)gnuism(265, tflag ? "traditional" : "ANSI");
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) {
31112099Sjoerg		/* remeber 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;
41891592Smarkm
41991592Smarkm	case NTSPEC:	/* this value unused */
42091592Smarkm		break;
42112099Sjoerg	}
42212099Sjoerg
42312099Sjoerg	/* Anything other is not accepted. */
42412099Sjoerg
42512099Sjoerg	dcs->d_terr = 1;
42612099Sjoerg	return (td);
42712099Sjoerg}
42812099Sjoerg
42912099Sjoerg/*
43012099Sjoerg * Remember the symbol of a typedef name (2nd arg) in a struct, union
43112099Sjoerg * or enum tag if the typedef name is the first defined for this tag.
43212099Sjoerg *
43312099Sjoerg * If the tag is unnamed, the typdef name is used for identification
43491592Smarkm * of this tag in lint2. Although its possible that more than one typedef
43512099Sjoerg * name is defined for one tag, the first name defined should be unique
43612099Sjoerg * if the tag is unnamed.
43712099Sjoerg */
43812099Sjoergstatic void
43991592Smarkmsettdsym(type_t *tp, sym_t *sym)
44012099Sjoerg{
44112099Sjoerg	tspec_t	t;
44212099Sjoerg
44312099Sjoerg	if ((t = tp->t_tspec) == STRUCT || t == UNION) {
44412099Sjoerg		if (tp->t_str->stdef == NULL)
44512099Sjoerg			tp->t_str->stdef = sym;
44612099Sjoerg	} else if (t == ENUM) {
44712099Sjoerg		if (tp->t_enum->etdef == NULL)
44812099Sjoerg			tp->t_enum->etdef = sym;
44912099Sjoerg	}
45012099Sjoerg}
45112099Sjoerg
45212099Sjoerg/*
45312099Sjoerg * Remember a qualifier which is part of the declaration specifiers
45412099Sjoerg * (and not the declarator) in the top element of the declaration stack.
45512099Sjoerg * Also detect multiple qualifiers of the same kind.
45612099Sjoerg
45791592Smarkm * The remembered qualifier is used by deftyp() to construct the type
45812099Sjoerg * for all declarators.
45912099Sjoerg */
46012099Sjoergvoid
46191592Smarkmaddqual(tqual_t q)
46212099Sjoerg{
46391592Smarkm
46412099Sjoerg	if (q == CONST) {
46512099Sjoerg		if (dcs->d_const) {
46612099Sjoerg			/* duplicate "%s" */
46712099Sjoerg			warning(10, "const");
46812099Sjoerg		}
46912099Sjoerg		dcs->d_const = 1;
47012099Sjoerg	} else {
47112099Sjoerg		if (q != VOLATILE)
47212099Sjoerg			lerror("addqual() 1");
47312099Sjoerg		if (dcs->d_volatile) {
47412099Sjoerg			/* duplicate "%s" */
47512099Sjoerg			warning(10, "volatile");
47612099Sjoerg		}
47712099Sjoerg		dcs->d_volatile = 1;
47812099Sjoerg	}
47912099Sjoerg}
48012099Sjoerg
48112099Sjoerg/*
48212099Sjoerg * Go to the next declaration level (structs, nested structs, blocks,
48312099Sjoerg * argument declaration lists ...)
48412099Sjoerg */
48512099Sjoergvoid
48691592Smarkmpushdecl(scl_t sc)
48712099Sjoerg{
48812099Sjoerg	dinfo_t	*di;
48912099Sjoerg
49012099Sjoerg	if (dflag)
49112099Sjoerg		(void)printf("pushdecl(%d)\n", (int)sc);
49212099Sjoerg
49312099Sjoerg	/* put a new element on the declaration stack */
49480284Sobrien	if ((di = calloc(1, sizeof (dinfo_t))) == NULL)
49580284Sobrien		nomem();
49612099Sjoerg	di->d_nxt = dcs;
49712099Sjoerg	dcs = di;
49812099Sjoerg	di->d_ctx = sc;
49912099Sjoerg	di->d_ldlsym = &di->d_dlsyms;
50012099Sjoerg}
50112099Sjoerg
50212099Sjoerg/*
50312099Sjoerg * Go back to previous declaration level
50412099Sjoerg */
50512099Sjoergvoid
50691592Smarkmpopdecl(void)
50712099Sjoerg{
50812099Sjoerg	dinfo_t	*di;
50912099Sjoerg
51012099Sjoerg	if (dflag)
51112099Sjoerg		(void)printf("popdecl(%d)\n", (int)dcs->d_ctx);
51212099Sjoerg
51312099Sjoerg	if (dcs->d_nxt == NULL)
51412099Sjoerg		lerror("popdecl() 1");
51512099Sjoerg	di = dcs;
51612099Sjoerg	dcs = di->d_nxt;
51712099Sjoerg	switch (di->d_ctx) {
51812099Sjoerg	case EXTERN:
51912099Sjoerg		/* there is nothing after external declarations */
52012099Sjoerg		lerror("popdecl() 2");
52112099Sjoerg		/* NOTREACHED */
52212099Sjoerg	case MOS:
52312099Sjoerg	case MOU:
52412099Sjoerg	case ENUMCON:
52512099Sjoerg		/*
52612099Sjoerg		 * Symbols declared in (nested) structs or enums are
52712099Sjoerg		 * part of the next level (they are removed from the
52812099Sjoerg		 * symbol table if the symbols of the outher level are
52912099Sjoerg		 * removed)
53012099Sjoerg		 */
53112099Sjoerg		if ((*dcs->d_ldlsym = di->d_dlsyms) != NULL)
53212099Sjoerg			dcs->d_ldlsym = di->d_ldlsym;
53312099Sjoerg		break;
53412099Sjoerg	case ARG:
53512099Sjoerg		/*
53612099Sjoerg		 * All symbols in dcs->d_dlsyms are introduced in old style
53712099Sjoerg		 * argument declarations (it's not clean, but possible).
53812099Sjoerg		 * They are appended to the list of symbols declared in
53912099Sjoerg		 * an old style argument identifier list or a new style
54012099Sjoerg		 * parameter type list.
54112099Sjoerg		 */
54212099Sjoerg		if (di->d_dlsyms != NULL) {
54312099Sjoerg			*di->d_ldlsym = dcs->d_fpsyms;
54412099Sjoerg			dcs->d_fpsyms = di->d_dlsyms;
54512099Sjoerg		}
54612099Sjoerg		break;
54712099Sjoerg	case ABSTRACT:
54812099Sjoerg		/*
54912099Sjoerg		 * casts and sizeof
55012099Sjoerg		 * Append all symbols declared in the abstract declaration
55112099Sjoerg		 * to the list of symbols declared in the surounding decl.
55212099Sjoerg		 * or block.
55312099Sjoerg		 * XXX I'm not sure whether they should be removed from the
55412099Sjoerg		 * symbol table now or later.
55512099Sjoerg		 */
55612099Sjoerg		if ((*dcs->d_ldlsym = di->d_dlsyms) != NULL)
55712099Sjoerg			dcs->d_ldlsym = di->d_ldlsym;
55812099Sjoerg		break;
55912099Sjoerg	case AUTO:
56012099Sjoerg		/* check usage of local vars */
56112099Sjoerg		chkusage(di);
56212099Sjoerg		/* FALLTHROUGH */
56312099Sjoerg	case PARG:
56412099Sjoerg		/* usage of arguments will be checked by funcend() */
56512099Sjoerg		rmsyms(di->d_dlsyms);
56612099Sjoerg		break;
56712099Sjoerg	default:
56812099Sjoerg		lerror("popdecl() 3");
56912099Sjoerg	}
57012099Sjoerg	free(di);
57112099Sjoerg}
57212099Sjoerg
57312099Sjoerg/*
57412099Sjoerg * Set flag d_asm in all declaration stack elements up to the
57512099Sjoerg * outermost one.
57612099Sjoerg *
57712099Sjoerg * This is used to mark compound statements which have, possibly in
57812099Sjoerg * nested compound statements, asm statements. For these compound
57912099Sjoerg * statements no warnings about unused or unitialized variables are
58012099Sjoerg * printed.
58112099Sjoerg *
58212099Sjoerg * There is no need to clear d_asm in dinfo structs with context AUTO,
58312099Sjoerg * because these structs are freed at the end of the compound statement.
58412099Sjoerg * But it must be cleard in the outermost dinfo struct, which has
58512099Sjoerg * context EXTERN. This could be done in clrtyp() and would work for
58612099Sjoerg * C, but not for C++ (due to mixed statements and declarations). Thus
58712099Sjoerg * we clear it in glclup(), which is used to do some cleanup after
58812099Sjoerg * global declarations/definitions.
58912099Sjoerg */
59012099Sjoergvoid
59191592Smarkmsetasm(void)
59212099Sjoerg{
59312099Sjoerg	dinfo_t	*di;
59412099Sjoerg
59512099Sjoerg	for (di = dcs; di != NULL; di = di->d_nxt)
59612099Sjoerg		di->d_asm = 1;
59712099Sjoerg}
59812099Sjoerg
59912099Sjoerg/*
60012099Sjoerg * Clean all elements of the top element of declaration stack which
60112099Sjoerg * will be used by the next declaration
60212099Sjoerg */
60312099Sjoergvoid
60491592Smarkmclrtyp(void)
60512099Sjoerg{
60691592Smarkm
60712099Sjoerg	dcs->d_atyp = dcs->d_smod = dcs->d_lmod = NOTSPEC;
60812099Sjoerg	dcs->d_scl = NOSCL;
60912099Sjoerg	dcs->d_type = NULL;
61012099Sjoerg	dcs->d_const = dcs->d_volatile = 0;
61112099Sjoerg	dcs->d_inline = 0;
61212099Sjoerg	dcs->d_mscl = dcs->d_terr = 0;
61312099Sjoerg	dcs->d_nedecl = 0;
61412099Sjoerg	dcs->d_notyp = 0;
61512099Sjoerg}
61612099Sjoerg
61712099Sjoerg/*
61812099Sjoerg * Create a type structure from the informations gathered in
61912099Sjoerg * the declaration stack.
62012099Sjoerg * Complain about storage classes which are not possible in current
62112099Sjoerg * context.
62212099Sjoerg */
62312099Sjoergvoid
62491592Smarkmdeftyp(void)
62512099Sjoerg{
62612099Sjoerg	tspec_t	t, s, l;
62712099Sjoerg	type_t	*tp;
62812099Sjoerg	scl_t	scl;
62912099Sjoerg
63012099Sjoerg	t = dcs->d_atyp;		/* CHAR, INT, FLOAT, DOUBLE, VOID */
63112099Sjoerg	s = dcs->d_smod;		/* SIGNED, UNSIGNED */
63212099Sjoerg	l = dcs->d_lmod;		/* SHORT, LONG, QUAD */
63312099Sjoerg	tp = dcs->d_type;
63412099Sjoerg	scl = dcs->d_scl;
63512099Sjoerg
63612099Sjoerg	if (t == NOTSPEC && s == NOTSPEC && l == NOTSPEC && tp == NULL)
63712099Sjoerg		dcs->d_notyp = 1;
63812099Sjoerg
63912099Sjoerg	if (tp != NULL && (t != NOTSPEC || s != NOTSPEC || l != NOTSPEC)) {
64012099Sjoerg		/* should never happen */
64112099Sjoerg		lerror("deftyp() 1");
64212099Sjoerg	}
64312099Sjoerg
64412099Sjoerg	if (tp == NULL) {
64512099Sjoerg		switch (t) {
64612099Sjoerg		case NOTSPEC:
64712099Sjoerg			t = INT;
64812099Sjoerg			/* FALLTHROUGH */
64912099Sjoerg		case INT:
65012099Sjoerg			if (s == NOTSPEC)
65112099Sjoerg				s = SIGNED;
65212099Sjoerg			break;
65312099Sjoerg		case CHAR:
65412099Sjoerg			if (l != NOTSPEC) {
65512099Sjoerg				dcs->d_terr = 1;
65612099Sjoerg				l = NOTSPEC;
65712099Sjoerg			}
65812099Sjoerg			break;
65912099Sjoerg		case FLOAT:
66012099Sjoerg			if (l == LONG) {
66112099Sjoerg				l = NOTSPEC;
66212099Sjoerg				t = DOUBLE;
66312099Sjoerg				if (!tflag)
66412099Sjoerg					/* use 'double' instead of ...  */
66512099Sjoerg					warning(6);
66612099Sjoerg			}
66712099Sjoerg			break;
66812099Sjoerg		case DOUBLE:
66912099Sjoerg			if (l == LONG) {
67012099Sjoerg				l = NOTSPEC;
67112099Sjoerg				t = LDOUBLE;
67212099Sjoerg				if (tflag)
67312099Sjoerg					/* 'long double' is illegal in ... */
67412099Sjoerg					warning(266);
67512099Sjoerg			}
67612099Sjoerg			break;
67712099Sjoerg		case VOID:
67812099Sjoerg			break;
67912099Sjoerg		default:
68012099Sjoerg			lerror("deftyp() 2");
68112099Sjoerg		}
68212099Sjoerg		if (t != INT && t != CHAR && (s != NOTSPEC || l != NOTSPEC)) {
68312099Sjoerg			dcs->d_terr = 1;
68412099Sjoerg			l = s = NOTSPEC;
68512099Sjoerg		}
68612099Sjoerg		if (l != NOTSPEC)
68712099Sjoerg			t = l;
68812099Sjoerg		dcs->d_type = gettyp(mrgtspec(t, s));
68912099Sjoerg	}
69012099Sjoerg
69112099Sjoerg	if (dcs->d_mscl) {
69212099Sjoerg		/* only one storage class allowed */
69312099Sjoerg		error(7);
69412099Sjoerg	}
69512099Sjoerg	if (dcs->d_terr) {
69612099Sjoerg		/* illegal type combination */
69712099Sjoerg		error(4);
69812099Sjoerg	}
69912099Sjoerg
70012099Sjoerg	if (dcs->d_ctx == EXTERN) {
70112099Sjoerg		if (scl == REG || scl == AUTO) {
70212099Sjoerg			/* illegal storage class */
70312099Sjoerg			error(8);
70412099Sjoerg			scl = NOSCL;
70512099Sjoerg		}
70612099Sjoerg	} else if (dcs->d_ctx == ARG || dcs->d_ctx == PARG) {
70712099Sjoerg		if (scl != NOSCL && scl != REG) {
70812099Sjoerg			/* only "register" valid ... */
70912099Sjoerg			error(9);
71012099Sjoerg			scl = NOSCL;
71112099Sjoerg		}
71212099Sjoerg	}
71312099Sjoerg
71412099Sjoerg	dcs->d_scl = scl;
71512099Sjoerg
71612099Sjoerg	if (dcs->d_const && dcs->d_type->t_const) {
71712099Sjoerg		if (!dcs->d_type->t_typedef)
71812099Sjoerg			lerror("deftyp() 3");
71912099Sjoerg		/* typedef already qualified with "%s" */
72012099Sjoerg		warning(68, "const");
72112099Sjoerg	}
72212099Sjoerg	if (dcs->d_volatile && dcs->d_type->t_volatile) {
72312099Sjoerg		if (!dcs->d_type->t_typedef)
72412099Sjoerg			lerror("deftyp() 4");
72512099Sjoerg		/* typedef already qualified with "%s" */
72612099Sjoerg		warning(68, "volatile");
72712099Sjoerg	}
72812099Sjoerg
72912099Sjoerg	if (dcs->d_const || dcs->d_volatile) {
73012099Sjoerg		dcs->d_type = duptyp(dcs->d_type);
73112099Sjoerg		dcs->d_type->t_const |= dcs->d_const;
73212099Sjoerg		dcs->d_type->t_volatile |= dcs->d_volatile;
73312099Sjoerg	}
73412099Sjoerg}
73512099Sjoerg
73612099Sjoerg/*
73712099Sjoerg * Merge type specifiers (char, ..., long long, signed, unsigned).
73812099Sjoerg */
73912099Sjoergstatic tspec_t
74091592Smarkmmrgtspec(tspec_t t, tspec_t s)
74112099Sjoerg{
74291592Smarkm
74312099Sjoerg	if (s == SIGNED || s == UNSIGN) {
74412099Sjoerg		if (t == CHAR) {
74512099Sjoerg			t = s == SIGNED ? SCHAR : UCHAR;
74612099Sjoerg		} else if (t == SHORT) {
74712099Sjoerg			t = s == SIGNED ? SHORT : USHORT;
74812099Sjoerg		} else if (t == INT) {
74912099Sjoerg			t = s == SIGNED ? INT : UINT;
75012099Sjoerg		} else if (t == LONG) {
75112099Sjoerg			t = s == SIGNED ? LONG : ULONG;
75212099Sjoerg		} else if (t == QUAD) {
75312099Sjoerg			t = s == SIGNED ? QUAD : UQUAD;
75412099Sjoerg		}
75512099Sjoerg	}
75612099Sjoerg
75712099Sjoerg	return (t);
75812099Sjoerg}
75912099Sjoerg
76012099Sjoerg/*
76112099Sjoerg * Return the length of a type in bit.
76212099Sjoerg *
76312099Sjoerg * Printing a message if the outhermost dimension of an array is 0 must
76412099Sjoerg * be done by the caller. All other problems are reported by length()
76512099Sjoerg * if name is not NULL.
76612099Sjoerg */
76712099Sjoergint
76891592Smarkmlength(type_t *tp, const char *name)
76912099Sjoerg{
77012099Sjoerg	int	elem, elsz;
77112099Sjoerg
77212099Sjoerg	elem = 1;
77391592Smarkm	while (tp && tp->t_tspec == ARRAY) {
77412099Sjoerg		elem *= tp->t_dim;
77512099Sjoerg		tp = tp->t_subt;
77612099Sjoerg	}
77791592Smarkm	if (tp == NULL)
77891592Smarkm		return -1;
77991592Smarkm
78012099Sjoerg	switch (tp->t_tspec) {
78112099Sjoerg	case FUNC:
78212099Sjoerg		/* compiler takes size of function */
78379307Skris		lerror("%s", msgs[12]);
78412099Sjoerg		/* NOTREACHED */
78512099Sjoerg	case STRUCT:
78612099Sjoerg	case UNION:
78712099Sjoerg		if (incompl(tp) && name != NULL) {
78812099Sjoerg			/* incomplete structure or union %s: %s */
78912099Sjoerg			error(31, tp->t_str->stag->s_name, name);
79012099Sjoerg		}
79112099Sjoerg		elsz = tp->t_str->size;
79212099Sjoerg		break;
79312099Sjoerg	case ENUM:
79412099Sjoerg		if (incompl(tp) && name != NULL) {
79512099Sjoerg			/* incomplete enum type: %s */
79612099Sjoerg			warning(13, name);
79712099Sjoerg		}
79812099Sjoerg		/* FALLTHROUGH */
79912099Sjoerg	default:
80012099Sjoerg		elsz = size(tp->t_tspec);
80112099Sjoerg		if (elsz <= 0)
80212099Sjoerg			lerror("length()");
80312099Sjoerg		break;
80412099Sjoerg	}
80512099Sjoerg	return (elem * elsz);
80612099Sjoerg}
80712099Sjoerg
80812099Sjoerg/*
80912099Sjoerg * Get the alignment of the given Type in bits.
81012099Sjoerg */
81112099Sjoergint
81291592Smarkmgetbound(type_t *tp)
81312099Sjoerg{
81412099Sjoerg	int	a;
81512099Sjoerg	tspec_t	t;
81612099Sjoerg
81791592Smarkm	while (tp && tp->t_tspec == ARRAY)
81812099Sjoerg		tp = tp->t_subt;
81912099Sjoerg
82091592Smarkm	if (tp == NULL)
82191592Smarkm		return -1;
82291592Smarkm
82312099Sjoerg	if ((t = tp->t_tspec) == STRUCT || t == UNION) {
82412099Sjoerg		a = tp->t_str->align;
82512099Sjoerg	} else if (t == FUNC) {
82612099Sjoerg		/* compiler takes alignment of function */
82712099Sjoerg		error(14);
828206424Srdivacky		a = LINT_ALIGN(1) * CHAR_BIT;
82912099Sjoerg	} else {
83012099Sjoerg		if ((a = size(t)) == 0) {
83112099Sjoerg			a = CHAR_BIT;
832206424Srdivacky		} else if (a > LINT_ALIGN(1) * CHAR_BIT) {
833206424Srdivacky			a = LINT_ALIGN(1) * CHAR_BIT;
83412099Sjoerg		}
83512099Sjoerg	}
836206424Srdivacky	if (a < CHAR_BIT || a > LINT_ALIGN(1) * CHAR_BIT)
83712099Sjoerg		lerror("getbound() 1");
83812099Sjoerg	return (a);
83912099Sjoerg}
84012099Sjoerg
84112099Sjoerg/*
84212099Sjoerg * Concatenate two lists of symbols by s_nxt. Used by declarations of
84312099Sjoerg * struct/union/enum elements and parameters.
84412099Sjoerg */
84512099Sjoergsym_t *
84691592Smarkmlnklst(sym_t *l1, sym_t *l2)
84712099Sjoerg{
84812099Sjoerg	sym_t	*l;
84912099Sjoerg
85012099Sjoerg	if ((l = l1) == NULL)
85112099Sjoerg		return (l2);
85212099Sjoerg	while (l1->s_nxt != NULL)
85312099Sjoerg		l1 = l1->s_nxt;
85412099Sjoerg	l1->s_nxt = l2;
85512099Sjoerg	return (l);
85612099Sjoerg}
85712099Sjoerg
85812099Sjoerg/*
85912099Sjoerg * Check if the type of the given symbol is valid and print an error
86012099Sjoerg * message if it is not.
86112099Sjoerg *
86212099Sjoerg * Invalid types are:
86312099Sjoerg * - arrays of incomlete types or functions
86412099Sjoerg * - functions returning arrays or functions
86512099Sjoerg * - void types other than type of function or pointer
86612099Sjoerg */
86712099Sjoergvoid
86891592Smarkmchktyp(sym_t *sym)
86912099Sjoerg{
87012099Sjoerg	tspec_t	to, t;
87112099Sjoerg	type_t	**tpp, *tp;
87212099Sjoerg
87312099Sjoerg	tpp = &sym->s_type;
87412099Sjoerg	to = NOTSPEC;
87512099Sjoerg	while ((tp = *tpp) != NULL) {
87612099Sjoerg		t = tp->t_tspec;
87712099Sjoerg		/*
87812099Sjoerg		 * If this is the type of an old style function definition,
87912099Sjoerg		 * a better warning is printed in funcdef().
88012099Sjoerg		 */
88112099Sjoerg		if (t == FUNC && !tp->t_proto &&
88212099Sjoerg		    !(to == NOTSPEC && sym->s_osdef)) {
88312099Sjoerg			if (sflag && hflag)
88412099Sjoerg				/* function declaration is not a prototype */
88512099Sjoerg				warning(287);
88612099Sjoerg		}
88712099Sjoerg		if (to == FUNC) {
88812099Sjoerg			if (t == FUNC || t == ARRAY) {
88912099Sjoerg				/* function returns illegal type */
89012099Sjoerg				error(15);
89112099Sjoerg				if (t == FUNC) {
89212099Sjoerg					*tpp = incref(*tpp, PTR);
89312099Sjoerg				} else {
89412099Sjoerg					*tpp = incref((*tpp)->t_subt, PTR);
89512099Sjoerg				}
89612099Sjoerg				return;
89712099Sjoerg			} else if (tp->t_const || tp->t_volatile) {
89812099Sjoerg				if (sflag) {	/* XXX oder better !tflag ? */
89912099Sjoerg					/* function cannot return const... */
90012099Sjoerg					warning(228);
90112099Sjoerg				}
90212099Sjoerg			}
90312099Sjoerg		} if (to == ARRAY) {
90412099Sjoerg			if (t == FUNC) {
90512099Sjoerg				/* array of function is illegal */
90612099Sjoerg				error(16);
90712099Sjoerg				*tpp = gettyp(INT);
90812099Sjoerg				return;
90912099Sjoerg			} else if (t == ARRAY && tp->t_dim == 0) {
91012099Sjoerg				/* null dimension */
91112099Sjoerg				error(17);
91212099Sjoerg				return;
91312099Sjoerg			} else if (t == VOID) {
91412099Sjoerg				/* illegal use of void */
91512099Sjoerg				error(18);
91612099Sjoerg				*tpp = gettyp(INT);
91712099Sjoerg#if 0	/* errors are produced by length() */
91812099Sjoerg			} else if (incompl(tp)) {
91912099Sjoerg				/* array of incomplete type */
92012099Sjoerg				if (sflag) {
92112099Sjoerg					error(301);
92212099Sjoerg				} else {
92312099Sjoerg					warning(301);
92412099Sjoerg				}
92512099Sjoerg#endif
92612099Sjoerg			}
92712099Sjoerg		} else if (to == NOTSPEC && t == VOID) {
92812099Sjoerg			if (dcs->d_ctx == PARG) {
92912099Sjoerg				if (sym->s_scl != ABSTRACT) {
93012099Sjoerg					if (sym->s_name == unnamed)
93112099Sjoerg						lerror("chktyp()");
93212099Sjoerg					/* void param cannot have name: %s */
93312099Sjoerg					error(61, sym->s_name);
93412099Sjoerg					*tpp = gettyp(INT);
93512099Sjoerg				}
93612099Sjoerg			} else if (dcs->d_ctx == ABSTRACT) {
93712099Sjoerg				/* ok */
93812099Sjoerg			} else if (sym->s_scl != TYPEDEF) {
93912099Sjoerg				/* void type for %s */
94012099Sjoerg				error(19, sym->s_name);
94112099Sjoerg				*tpp = gettyp(INT);
94212099Sjoerg			}
94312099Sjoerg		}
94412099Sjoerg		if (t == VOID && to != PTR) {
94512099Sjoerg			if (tp->t_const || tp->t_volatile) {
94612099Sjoerg				/* inappropriate qualifiers with "void" */
94712099Sjoerg				warning(69);
94812099Sjoerg				tp->t_const = tp->t_volatile = 0;
94912099Sjoerg			}
95012099Sjoerg		}
95112099Sjoerg		tpp = &tp->t_subt;
95212099Sjoerg		to = t;
95312099Sjoerg	}
95412099Sjoerg}
95512099Sjoerg
95612099Sjoerg/*
95712099Sjoerg * Process the declarator of a struct/union element.
95812099Sjoerg */
95912099Sjoergsym_t *
96091592Smarkmdecl1str(sym_t *dsym)
96112099Sjoerg{
96212099Sjoerg	type_t	*tp;
96312099Sjoerg	tspec_t	t;
96491592Smarkm	int	sz, len;
96591592Smarkm	int	o = 0;	/* Appease gcc */
96612099Sjoerg	scl_t	sc;
96712099Sjoerg
96812099Sjoerg	if ((sc = dsym->s_scl) != MOS && sc != MOU)
96912099Sjoerg		lerror("decl1str() 1");
97012099Sjoerg
97112099Sjoerg	if (dcs->d_rdcsym != NULL) {
97212099Sjoerg		if ((sc = dcs->d_rdcsym->s_scl) != MOS && sc != MOU)
97312099Sjoerg			/* should be ensured by storesym() */
97412099Sjoerg			lerror("decl1str() 2");
97512099Sjoerg		if (dsym->s_styp == dcs->d_rdcsym->s_styp) {
97612099Sjoerg			/* duplicate member name: %s */
97712099Sjoerg			error(33, dsym->s_name);
97812099Sjoerg			rmsym(dcs->d_rdcsym);
97912099Sjoerg		}
98012099Sjoerg	}
98112099Sjoerg
98212099Sjoerg	chktyp(dsym);
98312099Sjoerg
98412099Sjoerg	t = (tp = dsym->s_type)->t_tspec;
98512099Sjoerg
98612099Sjoerg	if (dsym->s_field) {
98712099Sjoerg		/*
98812099Sjoerg		 * bit field
98912099Sjoerg		 *
99012099Sjoerg		 * only unsigned und signed int are protable bit-field types
99112099Sjoerg		 *(at least in ANSI C, in traditional C only unsigned int)
99212099Sjoerg		 */
99312099Sjoerg		if (t == CHAR || t == UCHAR || t == SCHAR ||
99412099Sjoerg		    t == SHORT || t == USHORT || t == ENUM) {
99591592Smarkm			if (bitfieldtype_ok == 0) {
99691592Smarkm				if (sflag) {
99791592Smarkm					/*
99891592Smarkm					 * bit-field type '%s' invalid in
99991592Smarkm					 * ANSI C
100091592Smarkm					 */
100191592Smarkm					warning(273, tyname(tp));
100291592Smarkm				} else if (pflag) {
100391592Smarkm					/* nonportable bit-field type */
100491592Smarkm					warning(34);
100591592Smarkm				}
100612099Sjoerg			}
100712099Sjoerg		} else if (t == INT && dcs->d_smod == NOTSPEC) {
100891592Smarkm			if (pflag && bitfieldtype_ok == 0) {
100912099Sjoerg				/* nonportable bit-field type */
101012099Sjoerg				warning(34);
101112099Sjoerg			}
101212099Sjoerg		} else if (t != INT && t != UINT) {
101391592Smarkm			/*
101491592Smarkm			 * Non-integer types are always illegal for
101591592Smarkm			 * bitfields, regardless of BITFIELDTYPE.
101691592Smarkm			 * Integer types not dealt with above are
101791592Smarkm			 * okay only if BITFIELDTYPE is in effect.
101891592Smarkm			 */
101991592Smarkm			if (bitfieldtype_ok == 0 || isityp(t) == 0) {
102091592Smarkm				/* illegal bit-field type */
102191592Smarkm				error(35);
102291592Smarkm				sz = tp->t_flen;
102391592Smarkm				dsym->s_type = tp = duptyp(gettyp(t = INT));
102491592Smarkm				if ((tp->t_flen = sz) > size(t))
102591592Smarkm					tp->t_flen = size(t);
102691592Smarkm			}
102712099Sjoerg		}
102812099Sjoerg		if ((len = tp->t_flen) < 0 || len > size(t)) {
102912099Sjoerg			/* illegal bit-field size */
103012099Sjoerg			error(36);
103112099Sjoerg			tp->t_flen = size(t);
103212099Sjoerg		} else if (len == 0 && dsym->s_name != unnamed) {
103312099Sjoerg			/* zero size bit-field */
103412099Sjoerg			error(37);
103512099Sjoerg			tp->t_flen = size(t);
103612099Sjoerg		}
103712099Sjoerg		if (dsym->s_scl == MOU) {
103812099Sjoerg			/* illegal use of bit-field */
103912099Sjoerg			error(41);
104012099Sjoerg			dsym->s_type->t_isfield = 0;
104112099Sjoerg			dsym->s_field = 0;
104212099Sjoerg		}
104312099Sjoerg	} else if (t == FUNC) {
104412099Sjoerg		/* function illegal in structure or union */
104512099Sjoerg		error(38);
104612099Sjoerg		dsym->s_type = tp = incref(tp, t = PTR);
104712099Sjoerg	}
104812099Sjoerg
104912099Sjoerg	/*
105012099Sjoerg	 * bit-fields of length 0 are not warned about because length()
105112099Sjoerg	 * does not return the length of the bit-field but the length
105212099Sjoerg	 * of the type the bit-field is packed in (its ok)
105312099Sjoerg	 */
105412099Sjoerg	if ((sz = length(dsym->s_type, dsym->s_name)) == 0) {
105512099Sjoerg		if (t == ARRAY && dsym->s_type->t_dim == 0) {
105612099Sjoerg			/* illegal zero sized structure member: %s */
105712099Sjoerg			warning(39, dsym->s_name);
105812099Sjoerg		}
105912099Sjoerg	}
106012099Sjoerg
106112099Sjoerg	if (dcs->d_ctx == MOU) {
106212099Sjoerg		o = dcs->d_offset;
106312099Sjoerg		dcs->d_offset = 0;
106412099Sjoerg	}
106512099Sjoerg	if (dsym->s_field) {
106612099Sjoerg		align(getbound(tp), tp->t_flen);
106712099Sjoerg		dsym->s_value.v_quad = (dcs->d_offset / size(t)) * size(t);
106812099Sjoerg		tp->t_foffs = dcs->d_offset - (int)dsym->s_value.v_quad;
106912099Sjoerg		dcs->d_offset += tp->t_flen;
107012099Sjoerg	} else {
107112099Sjoerg		align(getbound(tp), 0);
107212099Sjoerg		dsym->s_value.v_quad = dcs->d_offset;
107312099Sjoerg		dcs->d_offset += sz;
107412099Sjoerg	}
107512099Sjoerg	if (dcs->d_ctx == MOU) {
107612099Sjoerg		if (o > dcs->d_offset)
107712099Sjoerg			dcs->d_offset = o;
107812099Sjoerg	}
107912099Sjoerg
108012099Sjoerg	chkfdef(dsym, 0);
108112099Sjoerg
108291592Smarkm	/*
108391592Smarkm	 * Clear the BITFIELDTYPE indicator after processing each
108491592Smarkm	 * structure element.
108591592Smarkm	 */
108691592Smarkm	bitfieldtype_ok = 0;
108791592Smarkm
108812099Sjoerg	return (dsym);
108912099Sjoerg}
109012099Sjoerg
109112099Sjoerg/*
109212099Sjoerg * Aligns next structure element as required.
109312099Sjoerg *
109412099Sjoerg * al contains the required alignment, len the length of a bit-field.
109512099Sjoerg */
109612099Sjoergstatic void
109791592Smarkmalign(int al, int len)
109812099Sjoerg{
109912099Sjoerg	int	no;
110012099Sjoerg
110112099Sjoerg	/*
110212099Sjoerg	 * The alignment of the current element becomes the alignment of
110312099Sjoerg	 * the struct/union if it is larger than the current alignment
110412099Sjoerg	 * of the struct/union.
110512099Sjoerg	 */
110612099Sjoerg	if (al > dcs->d_stralign)
110712099Sjoerg		dcs->d_stralign = al;
110891592Smarkm
110912099Sjoerg	no = (dcs->d_offset + (al - 1)) & ~(al - 1);
111012099Sjoerg	if (len == 0 || dcs->d_offset + len > no)
111112099Sjoerg		dcs->d_offset = no;
111212099Sjoerg}
111312099Sjoerg
111412099Sjoerg/*
111512099Sjoerg * Remember the width of the field in its type structure.
111612099Sjoerg */
111712099Sjoergsym_t *
111891592Smarkmbitfield(sym_t *dsym, int len)
111912099Sjoerg{
112091592Smarkm
112112099Sjoerg	if (dsym == NULL) {
112212099Sjoerg		dsym = getblk(sizeof (sym_t));
112312099Sjoerg		dsym->s_name = unnamed;
112412099Sjoerg		dsym->s_kind = FMOS;
112512099Sjoerg		dsym->s_scl = MOS;
112691592Smarkm		dsym->s_type = gettyp(UINT);
112712099Sjoerg		dsym->s_blklev = -1;
112812099Sjoerg	}
112912099Sjoerg	dsym->s_type = duptyp(dsym->s_type);
113012099Sjoerg	dsym->s_type->t_isfield = 1;
113112099Sjoerg	dsym->s_type->t_flen = len;
113212099Sjoerg	dsym->s_field = 1;
113312099Sjoerg	return (dsym);
113412099Sjoerg}
113512099Sjoerg
113612099Sjoerg/*
113712099Sjoerg * Collect informations about a sequence of asterisks and qualifiers
113812099Sjoerg * in a list of type pqinf_t.
113912099Sjoerg * Qualifiers refer always to the left asterisk. The rightmost asterisk
114012099Sjoerg * will be at the top of the list.
114112099Sjoerg */
114212099Sjoergpqinf_t *
114391592Smarkmmergepq(pqinf_t *p1, pqinf_t *p2)
114412099Sjoerg{
114512099Sjoerg	pqinf_t	*p;
114612099Sjoerg
114712099Sjoerg	if (p2->p_pcnt != 0) {
114812099Sjoerg		/* left '*' at the end of the list */
114991592Smarkm		for (p = p2; p->p_nxt != NULL; p = p->p_nxt)
115091592Smarkm			continue;
115112099Sjoerg		p->p_nxt = p1;
115212099Sjoerg		return (p2);
115312099Sjoerg	} else {
115412099Sjoerg		if (p2->p_const) {
115512099Sjoerg			if (p1->p_const) {
115612099Sjoerg				/* duplicate %s */
115712099Sjoerg				warning(10, "const");
115812099Sjoerg			}
115912099Sjoerg			p1->p_const = 1;
116012099Sjoerg		}
116112099Sjoerg		if (p2->p_volatile) {
116212099Sjoerg			if (p1->p_volatile) {
116312099Sjoerg				/* duplicate %s */
116412099Sjoerg				warning(10, "volatile");
116512099Sjoerg			}
116612099Sjoerg			p1->p_volatile = 1;
116712099Sjoerg		}
116812099Sjoerg		free(p2);
116912099Sjoerg		return (p1);
117012099Sjoerg	}
117112099Sjoerg}
117212099Sjoerg
117312099Sjoerg/*
117412099Sjoerg * Followint 3 functions extend the type of a declarator with
117512099Sjoerg * pointer, function and array types.
117612099Sjoerg *
117712099Sjoerg * The current type is the Type built by deftyp() (dcs->d_type) and
117812099Sjoerg * pointer, function and array types already added for this
117912099Sjoerg * declarator. The new type extension is inserted between both.
118012099Sjoerg */
118112099Sjoergsym_t *
118291592Smarkmaddptr(sym_t *decl, pqinf_t *pi)
118312099Sjoerg{
118412099Sjoerg	type_t	**tpp, *tp;
118512099Sjoerg	pqinf_t	*npi;
118612099Sjoerg
118712099Sjoerg	tpp = &decl->s_type;
118891592Smarkm	while (*tpp && *tpp != dcs->d_type)
118912099Sjoerg		tpp = &(*tpp)->t_subt;
119091592Smarkm	if (*tpp == NULL)
119191592Smarkm		return decl;
119212099Sjoerg
119312099Sjoerg	while (pi != NULL) {
119412099Sjoerg		*tpp = tp = getblk(sizeof (type_t));
119512099Sjoerg		tp->t_tspec = PTR;
119612099Sjoerg		tp->t_const = pi->p_const;
119712099Sjoerg		tp->t_volatile = pi->p_volatile;
119812099Sjoerg		*(tpp = &tp->t_subt) = dcs->d_type;
119912099Sjoerg		npi = pi->p_nxt;
120012099Sjoerg		free(pi);
120112099Sjoerg		pi = npi;
120212099Sjoerg	}
120312099Sjoerg	return (decl);
120412099Sjoerg}
120512099Sjoerg
120612099Sjoerg/*
120712099Sjoerg * If a dimension was specified, dim is 1, otherwise 0
120812099Sjoerg * n is the specified dimension
120912099Sjoerg */
121012099Sjoergsym_t *
121191592Smarkmaddarray(sym_t *decl, int dim, int n)
121212099Sjoerg{
121312099Sjoerg	type_t	**tpp, *tp;
121412099Sjoerg
121512099Sjoerg	tpp = &decl->s_type;
121691592Smarkm	while (*tpp && *tpp != dcs->d_type)
121712099Sjoerg		tpp = &(*tpp)->t_subt;
121891592Smarkm	if (*tpp == NULL)
121991592Smarkm	    return decl;
122012099Sjoerg
122112099Sjoerg	*tpp = tp = getblk(sizeof (type_t));
122212099Sjoerg	tp->t_tspec = ARRAY;
122312099Sjoerg	tp->t_subt = dcs->d_type;
122412099Sjoerg	tp->t_dim = n;
122512099Sjoerg
122612099Sjoerg	if (n < 0) {
122712099Sjoerg		/* zero or negative array dimension */
122812099Sjoerg		error(20);
122912099Sjoerg		n = 0;
123012099Sjoerg	} else if (n == 0 && dim) {
123112099Sjoerg		/* zero or negative array dimension */
123212099Sjoerg		warning(20);
123312099Sjoerg	} else if (n == 0 && !dim) {
123412099Sjoerg		/* is incomplete type */
123512099Sjoerg		setcompl(tp, 1);
123612099Sjoerg	}
123712099Sjoerg
123812099Sjoerg	return (decl);
123912099Sjoerg}
124012099Sjoerg
124112099Sjoergsym_t *
124291592Smarkmaddfunc(sym_t *decl, sym_t *args)
124312099Sjoerg{
124412099Sjoerg	type_t	**tpp, *tp;
124512099Sjoerg
124612099Sjoerg	if (dcs->d_proto) {
124712099Sjoerg		if (tflag)
124812099Sjoerg			/* function prototypes are illegal in traditional C */
124912099Sjoerg			warning(270);
125012099Sjoerg		args = nsfunc(decl, args);
125112099Sjoerg	} else {
125212099Sjoerg		osfunc(decl, args);
125312099Sjoerg	}
125412099Sjoerg
125512099Sjoerg	/*
125612099Sjoerg	 * The symbols are removed from the symbol table by popdecl() after
125712099Sjoerg	 * addfunc(). To be able to restore them if this is a function
125812099Sjoerg	 * definition, a pointer to the list of all symbols is stored in
125912099Sjoerg	 * dcs->d_nxt->d_fpsyms. Also a list of the arguments (concatenated
126012099Sjoerg	 * by s_nxt) is stored in dcs->d_nxt->d_fargs.
126112099Sjoerg	 * (dcs->d_nxt must be used because *dcs is the declaration stack
126212099Sjoerg	 * element created for the list of params and is removed after
126312099Sjoerg	 * addfunc())
126412099Sjoerg	 */
126512099Sjoerg	if (dcs->d_nxt->d_ctx == EXTERN &&
126612099Sjoerg	    decl->s_type == dcs->d_nxt->d_type) {
126712099Sjoerg		dcs->d_nxt->d_fpsyms = dcs->d_dlsyms;
126812099Sjoerg		dcs->d_nxt->d_fargs = args;
126912099Sjoerg	}
127012099Sjoerg
127112099Sjoerg	tpp = &decl->s_type;
127291592Smarkm	while (*tpp && *tpp != dcs->d_nxt->d_type)
127312099Sjoerg		tpp = &(*tpp)->t_subt;
127491592Smarkm	if (*tpp == NULL)
127591592Smarkm	    return decl;
127612099Sjoerg
127712099Sjoerg	*tpp = tp = getblk(sizeof (type_t));
127812099Sjoerg	tp->t_tspec = FUNC;
127912099Sjoerg	tp->t_subt = dcs->d_nxt->d_type;
128012099Sjoerg	if ((tp->t_proto = dcs->d_proto) != 0)
128112099Sjoerg		tp->t_args = args;
128212099Sjoerg	tp->t_vararg = dcs->d_vararg;
128312099Sjoerg
128412099Sjoerg	return (decl);
128512099Sjoerg}
128612099Sjoerg
128712099Sjoerg/*
128812099Sjoerg * Called for new style function declarations.
128912099Sjoerg */
129012099Sjoerg/* ARGSUSED */
129112099Sjoergstatic sym_t *
129291592Smarkmnsfunc(sym_t *decl, sym_t *args)
129312099Sjoerg{
129412099Sjoerg	sym_t	*arg, *sym;
129512099Sjoerg	scl_t	sc;
129612099Sjoerg	int	n;
129712099Sjoerg
129812099Sjoerg	/*
129912099Sjoerg	 * Declarations of structs/unions/enums in param lists are legal,
130012099Sjoerg	 * but senseless.
130112099Sjoerg	 */
130212099Sjoerg	for (sym = dcs->d_dlsyms; sym != NULL; sym = sym->s_dlnxt) {
130312099Sjoerg		sc = sym->s_scl;
130412099Sjoerg		if (sc == STRTAG || sc == UNIONTAG || sc == ENUMTAG) {
130512099Sjoerg			/* dubious tag declaration: %s %s */
130612099Sjoerg			warning(85, scltoa(sc), sym->s_name);
130712099Sjoerg		}
130812099Sjoerg	}
130912099Sjoerg
131012099Sjoerg	n = 1;
131112099Sjoerg	for (arg = args; arg != NULL; arg = arg->s_nxt) {
131212099Sjoerg		if (arg->s_type->t_tspec == VOID) {
131312099Sjoerg			if (n > 1 || arg->s_nxt != NULL) {
131412099Sjoerg				/* "void" must be sole parameter */
131512099Sjoerg				error(60);
131612099Sjoerg				arg->s_type = gettyp(INT);
131712099Sjoerg			}
131812099Sjoerg		}
131912099Sjoerg		n++;
132012099Sjoerg	}
132112099Sjoerg
132212099Sjoerg	/* return NULL if first param is VOID */
132312099Sjoerg	return (args != NULL && args->s_type->t_tspec != VOID ? args : NULL);
132412099Sjoerg}
132512099Sjoerg
132612099Sjoerg/*
132712099Sjoerg * Called for old style function declarations.
132812099Sjoerg */
132912099Sjoergstatic void
133091592Smarkmosfunc(sym_t *decl, sym_t *args)
133112099Sjoerg{
133291592Smarkm
133312099Sjoerg	/*
133412099Sjoerg	 * Remember list of params only if this is really seams to be
133512099Sjoerg	 * a function definition.
133612099Sjoerg	 */
133712099Sjoerg	if (dcs->d_nxt->d_ctx == EXTERN &&
133812099Sjoerg	    decl->s_type == dcs->d_nxt->d_type) {
133912099Sjoerg		/*
134012099Sjoerg		 * We assume that this becomes a function definition. If
134191592Smarkm		 * we are wrong, its corrected in chkfdef().
134212099Sjoerg		 */
134312099Sjoerg		if (args != NULL) {
134412099Sjoerg			decl->s_osdef = 1;
134512099Sjoerg			decl->s_args = args;
134612099Sjoerg		}
134712099Sjoerg	} else {
134812099Sjoerg		if (args != NULL)
134912099Sjoerg			/* function prototype parameters must have types */
135012099Sjoerg			warning(62);
135112099Sjoerg	}
135212099Sjoerg}
135312099Sjoerg
135412099Sjoerg/*
135512099Sjoerg * Lists of Identifiers in functions declarations are allowed only if
135612099Sjoerg * its also a function definition. If this is not the case, print a
135712099Sjoerg * error message.
135812099Sjoerg */
135912099Sjoergvoid
136091592Smarkmchkfdef(sym_t *sym, int msg)
136112099Sjoerg{
136291592Smarkm
136312099Sjoerg	if (sym->s_osdef) {
136412099Sjoerg		if (msg) {
136512099Sjoerg			/* incomplete or misplaced function definition */
136612099Sjoerg			error(22);
136712099Sjoerg		}
136812099Sjoerg		sym->s_osdef = 0;
136912099Sjoerg		sym->s_args = NULL;
137012099Sjoerg	}
137112099Sjoerg}
137212099Sjoerg
137312099Sjoerg/*
137412099Sjoerg * Process the name in a declarator.
137512099Sjoerg * If the symbol does already exists, a new one is created.
137612099Sjoerg * The symbol becomes one of the storage classes EXTERN, STATIC, AUTO or
137712099Sjoerg * TYPEDEF.
137812099Sjoerg * s_def and s_reg are valid after dname().
137912099Sjoerg */
138012099Sjoergsym_t *
138191592Smarkmdname(sym_t *sym)
138212099Sjoerg{
138391592Smarkm	scl_t	sc = NOSCL;
138412099Sjoerg
138512099Sjoerg	if (sym->s_scl == NOSCL) {
138612099Sjoerg		dcs->d_rdcsym = NULL;
138712099Sjoerg	} else if (sym->s_defarg) {
138812099Sjoerg		sym->s_defarg = 0;
138912099Sjoerg		dcs->d_rdcsym = NULL;
139012099Sjoerg	} else {
139112099Sjoerg		dcs->d_rdcsym = sym;
139212099Sjoerg		sym = pushdown(sym);
139312099Sjoerg	}
139412099Sjoerg
139512099Sjoerg	switch (dcs->d_ctx) {
139612099Sjoerg	case MOS:
139712099Sjoerg	case MOU:
139812099Sjoerg		/* Parent setzen */
139912099Sjoerg		sym->s_styp = dcs->d_tagtyp->t_str;
140012099Sjoerg		sym->s_def = DEF;
140112099Sjoerg		sym->s_value.v_tspec = INT;
140212099Sjoerg		sc = dcs->d_ctx;
140312099Sjoerg		break;
140412099Sjoerg	case EXTERN:
140512099Sjoerg		/*
140612099Sjoerg		 * static and external symbols without "extern" are
140712099Sjoerg		 * considered to be tentative defined, external
140812099Sjoerg		 * symbols with "extern" are declared, and typedef names
140912099Sjoerg		 * are defined. Tentative defined and declared symbols
141012099Sjoerg		 * may become defined if an initializer is present or
141112099Sjoerg		 * this is a function definition.
141212099Sjoerg		 */
141312099Sjoerg		if ((sc = dcs->d_scl) == NOSCL) {
141412099Sjoerg			sc = EXTERN;
141512099Sjoerg			sym->s_def = TDEF;
141612099Sjoerg		} else if (sc == STATIC) {
141712099Sjoerg			sym->s_def = TDEF;
141812099Sjoerg		} else if (sc == TYPEDEF) {
141912099Sjoerg			sym->s_def = DEF;
142012099Sjoerg		} else if (sc == EXTERN) {
142112099Sjoerg			sym->s_def = DECL;
142212099Sjoerg		} else {
142312099Sjoerg			lerror("dname() 1");
142412099Sjoerg		}
142512099Sjoerg		break;
142612099Sjoerg	case PARG:
142712099Sjoerg		sym->s_arg = 1;
142812099Sjoerg		/* FALLTHROUGH */
142912099Sjoerg	case ARG:
143012099Sjoerg		if ((sc = dcs->d_scl) == NOSCL) {
143112099Sjoerg			sc = AUTO;
143212099Sjoerg		} else if (sc == REG) {
143312099Sjoerg			sym->s_reg = 1;
143412099Sjoerg			sc = AUTO;
143512099Sjoerg		} else {
143612099Sjoerg			lerror("dname() 2");
143712099Sjoerg		}
143812099Sjoerg		sym->s_def = DEF;
143912099Sjoerg		break;
144012099Sjoerg	case AUTO:
144112099Sjoerg		if ((sc = dcs->d_scl) == NOSCL) {
144212099Sjoerg			/*
144312099Sjoerg			 * XXX somewhat ugly because we dont know whether
144412099Sjoerg			 * this is AUTO or EXTERN (functions). If we are
144512099Sjoerg			 * wrong it must be corrected in decl1loc(), where
144691592Smarkm			 * we have the necessary type information.
144712099Sjoerg			 */
144812099Sjoerg			sc = AUTO;
144912099Sjoerg			sym->s_def = DEF;
145012099Sjoerg		} else if (sc == AUTO || sc == STATIC || sc == TYPEDEF) {
145112099Sjoerg			sym->s_def = DEF;
145212099Sjoerg		} else if (sc == REG) {
145312099Sjoerg			sym->s_reg = 1;
145412099Sjoerg			sc = AUTO;
145512099Sjoerg			sym->s_def = DEF;
145612099Sjoerg		} else if (sc == EXTERN) {
145712099Sjoerg			sym->s_def = DECL;
145812099Sjoerg		} else {
145912099Sjoerg			lerror("dname() 3");
146012099Sjoerg		}
146112099Sjoerg		break;
146212099Sjoerg	default:
146312099Sjoerg		lerror("dname() 4");
146412099Sjoerg	}
146512099Sjoerg	sym->s_scl = sc;
146612099Sjoerg
146712099Sjoerg	sym->s_type = dcs->d_type;
146812099Sjoerg
146912099Sjoerg	dcs->d_fpsyms = NULL;
147012099Sjoerg
147112099Sjoerg	return (sym);
147212099Sjoerg}
147312099Sjoerg
147412099Sjoerg/*
147512099Sjoerg * Process a name in the list of formal params in an old style function
147612099Sjoerg * definition.
147712099Sjoerg */
147812099Sjoergsym_t *
147991592Smarkminame(sym_t *sym)
148012099Sjoerg{
148191592Smarkm
148212099Sjoerg	if (sym->s_scl != NOSCL) {
148312099Sjoerg		if (blklev == sym->s_blklev) {
148412099Sjoerg			/* redeclaration of formal parameter %s */
148512099Sjoerg			error(21, sym->s_name);
148612099Sjoerg			if (!sym->s_defarg)
148712099Sjoerg				lerror("iname()");
148812099Sjoerg		}
148912099Sjoerg		sym = pushdown(sym);
149012099Sjoerg	}
149112099Sjoerg	sym->s_type = gettyp(INT);
149212099Sjoerg	sym->s_scl = AUTO;
149312099Sjoerg	sym->s_def = DEF;
149412099Sjoerg	sym->s_defarg = sym->s_arg = 1;
149512099Sjoerg	return (sym);
149612099Sjoerg}
149712099Sjoerg
149812099Sjoerg/*
149912099Sjoerg * Create the type of a tag.
150012099Sjoerg *
150112099Sjoerg * tag points to the symbol table entry of the tag
150212099Sjoerg * kind is the kind of the tag (STRUCT/UNION/ENUM)
150312099Sjoerg * decl is 1 if the type of the tag will be completed in this declaration
150412099Sjoerg * (the following token is T_LBRACE)
150512099Sjoerg * semi is 1 if the following token is T_SEMI
150612099Sjoerg */
150712099Sjoergtype_t *
150891592Smarkmmktag(sym_t *tag, tspec_t kind, int decl, int semi)
150912099Sjoerg{
151091592Smarkm	scl_t	scl = NOSCL;
151112099Sjoerg	type_t	*tp;
151212099Sjoerg
151312099Sjoerg	if (kind == STRUCT) {
151412099Sjoerg		scl = STRTAG;
151512099Sjoerg	} else if (kind == UNION) {
151612099Sjoerg		scl = UNIONTAG;
151712099Sjoerg	} else if (kind == ENUM) {
151812099Sjoerg		scl = ENUMTAG;
151912099Sjoerg	} else {
152012099Sjoerg		lerror("mktag()");
152112099Sjoerg	}
152212099Sjoerg
152312099Sjoerg	if (tag != NULL) {
152412099Sjoerg		if (tag->s_scl != NOSCL) {
152512099Sjoerg			tag = newtag(tag, scl, decl, semi);
152612099Sjoerg		} else {
152712099Sjoerg			/* a new tag, no empty declaration */
152812099Sjoerg			dcs->d_nxt->d_nedecl = 1;
152912099Sjoerg			if (scl == ENUMTAG && !decl) {
153012099Sjoerg				if (!tflag && (sflag || pflag))
153112099Sjoerg					/* forward reference to enum type */
153212099Sjoerg					warning(42);
153312099Sjoerg			}
153412099Sjoerg		}
153512099Sjoerg		if (tag->s_scl == NOSCL) {
153612099Sjoerg			tag->s_scl = scl;
153712099Sjoerg			tag->s_type = tp = getblk(sizeof (type_t));
153812099Sjoerg		} else {
153912099Sjoerg			tp = tag->s_type;
154012099Sjoerg		}
154112099Sjoerg	} else {
154212099Sjoerg		tag = getblk(sizeof (sym_t));
154312099Sjoerg		tag->s_name = unnamed;
154491592Smarkm		UNIQUE_CURR_POS(tag->s_dpos);
154512099Sjoerg		tag->s_kind = FTAG;
154612099Sjoerg		tag->s_scl = scl;
154712099Sjoerg		tag->s_blklev = -1;
154812099Sjoerg		tag->s_type = tp = getblk(sizeof (type_t));
154912099Sjoerg		dcs->d_nxt->d_nedecl = 1;
155012099Sjoerg	}
155112099Sjoerg
155212099Sjoerg	if (tp->t_tspec == NOTSPEC) {
155312099Sjoerg		tp->t_tspec = kind;
155412099Sjoerg		if (kind != ENUM) {
155512099Sjoerg			tp->t_str = getblk(sizeof (str_t));
155612099Sjoerg			tp->t_str->align = CHAR_BIT;
155712099Sjoerg			tp->t_str->stag = tag;
155812099Sjoerg		} else {
155912099Sjoerg			tp->t_isenum = 1;
156012099Sjoerg			tp->t_enum = getblk(sizeof (enum_t));
156112099Sjoerg			tp->t_enum->etag = tag;
156212099Sjoerg		}
156312099Sjoerg		/* ist unvollstaendiger Typ */
156412099Sjoerg		setcompl(tp, 1);
156512099Sjoerg	}
156612099Sjoerg
156712099Sjoerg	return (tp);
156812099Sjoerg}
156912099Sjoerg
157012099Sjoerg/*
157112099Sjoerg * Checks all possible cases of tag redeclarations.
157212099Sjoerg * decl is 1 if T_LBRACE follows
157312099Sjoerg * semi is 1 if T_SEMI follows
157412099Sjoerg */
157512099Sjoergstatic sym_t *
157691592Smarkmnewtag(sym_t *tag, scl_t scl, int decl, int semi)
157712099Sjoerg{
157891592Smarkm
157912099Sjoerg	if (tag->s_blklev < blklev) {
158012099Sjoerg		if (semi) {
158112099Sjoerg			/* "struct a;" */
158212099Sjoerg			if (!tflag) {
158312099Sjoerg				if (!sflag)
158412099Sjoerg					/* decl. introduces new type ... */
158512099Sjoerg					warning(44, scltoa(scl), tag->s_name);
158612099Sjoerg				tag = pushdown(tag);
158712099Sjoerg			} else if (tag->s_scl != scl) {
158812099Sjoerg				/* base type is really "%s %s" */
158912099Sjoerg				warning(45, scltoa(tag->s_scl), tag->s_name);
159012099Sjoerg			}
159112099Sjoerg			dcs->d_nxt->d_nedecl = 1;
159212099Sjoerg		} else if (decl) {
159391592Smarkm			/* "struct a { ... } " */
159412099Sjoerg			if (hflag)
159512099Sjoerg				/* redefinition hides earlier one: %s */
159612099Sjoerg				warning(43, tag->s_name);
159712099Sjoerg			tag = pushdown(tag);
159812099Sjoerg			dcs->d_nxt->d_nedecl = 1;
159912099Sjoerg		} else if (tag->s_scl != scl) {
160012099Sjoerg			/* base type is really "%s %s" */
160112099Sjoerg			warning(45, scltoa(tag->s_scl), tag->s_name);
160212099Sjoerg			/* declaration introduces new type in ANSI C: %s %s */
160312099Sjoerg			if (!sflag)
160412099Sjoerg				warning(44, scltoa(scl), tag->s_name);
160512099Sjoerg			tag = pushdown(tag);
160612099Sjoerg			dcs->d_nxt->d_nedecl = 1;
160712099Sjoerg		}
160812099Sjoerg	} else {
160912099Sjoerg		if (tag->s_scl != scl) {
161012099Sjoerg			/* (%s) tag redeclared */
161112099Sjoerg			error(46, scltoa(tag->s_scl));
161212099Sjoerg			prevdecl(-1, tag);
161312099Sjoerg			tag = pushdown(tag);
161412099Sjoerg			dcs->d_nxt->d_nedecl = 1;
161512099Sjoerg		} else if (decl && !incompl(tag->s_type)) {
161612099Sjoerg			/* (%s) tag redeclared */
161712099Sjoerg			error(46, scltoa(tag->s_scl));
161812099Sjoerg			prevdecl(-1, tag);
161912099Sjoerg			tag = pushdown(tag);
162012099Sjoerg			dcs->d_nxt->d_nedecl = 1;
162112099Sjoerg		} else if (semi || decl) {
162212099Sjoerg			dcs->d_nxt->d_nedecl = 1;
162312099Sjoerg		}
162412099Sjoerg	}
162512099Sjoerg	return (tag);
162612099Sjoerg}
162712099Sjoerg
162812099Sjoergconst char *
162991592Smarkmscltoa(scl_t sc)
163012099Sjoerg{
163112099Sjoerg	const	char *s;
163212099Sjoerg
163312099Sjoerg	switch (sc) {
163412099Sjoerg	case EXTERN:	s = "extern";	break;
163512099Sjoerg	case STATIC:	s = "static";	break;
163612099Sjoerg	case AUTO:	s = "auto";	break;
163712099Sjoerg	case REG:	s = "register";	break;
163812099Sjoerg	case TYPEDEF:	s = "typedef";	break;
163912099Sjoerg	case STRTAG:	s = "struct";	break;
164012099Sjoerg	case UNIONTAG:	s = "union";	break;
164112099Sjoerg	case ENUMTAG:	s = "enum";	break;
164212099Sjoerg	default:	lerror("tagttoa()");
164312099Sjoerg	}
164412099Sjoerg	return (s);
164512099Sjoerg}
164612099Sjoerg
164712099Sjoerg/*
164812099Sjoerg * Completes the type of a tag in a struct/union/enum declaration.
164912099Sjoerg * tp points to the type of the, tag, fmem to the list of members/enums.
165012099Sjoerg */
165112099Sjoergtype_t *
165291592Smarkmcompltag(type_t *tp, sym_t *fmem)
165312099Sjoerg{
165412099Sjoerg	tspec_t	t;
165512099Sjoerg	str_t	*sp;
165612099Sjoerg	int	n;
165712099Sjoerg	sym_t	*mem;
165812099Sjoerg
165912099Sjoerg	/* from now a complete type */
166012099Sjoerg	setcompl(tp, 0);
166112099Sjoerg
166212099Sjoerg	if ((t = tp->t_tspec) != ENUM) {
166312099Sjoerg		align(dcs->d_stralign, 0);
166412099Sjoerg		sp = tp->t_str;
166512099Sjoerg		sp->align = dcs->d_stralign;
166612099Sjoerg		sp->size = dcs->d_offset;
166712099Sjoerg		sp->memb = fmem;
166812099Sjoerg		if (sp->size == 0) {
166912099Sjoerg			/* zero sized %s */
167012099Sjoerg			(void)gnuism(47, ttab[t].tt_name);
167112099Sjoerg		} else {
167212099Sjoerg			n = 0;
167312099Sjoerg			for (mem = fmem; mem != NULL; mem = mem->s_nxt) {
167412099Sjoerg				if (mem->s_name != unnamed)
167512099Sjoerg					n++;
167612099Sjoerg			}
167712099Sjoerg			if (n == 0) {
167812099Sjoerg				/* %s has no named members */
167912099Sjoerg				warning(65,
168012099Sjoerg					t == STRUCT ? "structure" : "union");
168112099Sjoerg			}
168212099Sjoerg		}
168312099Sjoerg	} else {
168412099Sjoerg		tp->t_enum->elem = fmem;
168512099Sjoerg	}
168612099Sjoerg	return (tp);
168712099Sjoerg}
168812099Sjoerg
168912099Sjoerg/*
169012099Sjoerg * Processes the name of an enumerator in en enum declaration.
169112099Sjoerg *
169212099Sjoerg * sym points to the enumerator
169312099Sjoerg * val is the value of the enumerator
169491592Smarkm * impl is 1 if the value of the enumerator was not explicit specified.
169512099Sjoerg */
169612099Sjoergsym_t *
169791592Smarkmename(sym_t *sym, int val, int impl)
169812099Sjoerg{
169991592Smarkm
170012099Sjoerg	if (sym->s_scl) {
170112099Sjoerg		if (sym->s_blklev == blklev) {
170212099Sjoerg			/* no hflag, because this is illegal!!! */
170312099Sjoerg			if (sym->s_arg) {
170412099Sjoerg				/* enumeration constant hides parameter: %s */
170512099Sjoerg				warning(57, sym->s_name);
170612099Sjoerg			} else {
170712099Sjoerg				/* redeclaration of %s */
170812099Sjoerg				error(27, sym->s_name);
170912099Sjoerg				/*
171012099Sjoerg				 * inside blocks it should not too complicated
171112099Sjoerg				 * to find the position of the previous
171212099Sjoerg				 * declaration
171312099Sjoerg				 */
171412099Sjoerg				if (blklev == 0)
171512099Sjoerg					prevdecl(-1, sym);
171612099Sjoerg			}
171712099Sjoerg		} else {
171812099Sjoerg			if (hflag)
171912099Sjoerg				/* redefinition hides earlier one: %s */
172012099Sjoerg				warning(43, sym->s_name);
172112099Sjoerg		}
172212099Sjoerg		sym = pushdown(sym);
172312099Sjoerg	}
172412099Sjoerg	sym->s_scl = ENUMCON;
172512099Sjoerg	sym->s_type = dcs->d_tagtyp;
172612099Sjoerg	sym->s_value.v_tspec = INT;
172712099Sjoerg	sym->s_value.v_quad = val;
172812099Sjoerg	if (impl && val - 1 == INT_MAX) {
172912099Sjoerg		/* overflow in enumeration values: %s */
173012099Sjoerg		warning(48, sym->s_name);
173112099Sjoerg	}
173212099Sjoerg	enumval = val + 1;
173312099Sjoerg	return (sym);
173412099Sjoerg}
173512099Sjoerg
173612099Sjoerg/*
173712099Sjoerg * Process a single external declarator.
173812099Sjoerg */
173912099Sjoergvoid
174091592Smarkmdecl1ext(sym_t *dsym, int initflg)
174112099Sjoerg{
174212099Sjoerg	int	warn, rval, redec;
174312099Sjoerg	sym_t	*rdsym;
174412099Sjoerg
174512099Sjoerg	chkfdef(dsym, 1);
174612099Sjoerg
174712099Sjoerg	chktyp(dsym);
174812099Sjoerg
174912099Sjoerg	if (initflg && !(initerr = chkinit(dsym)))
175012099Sjoerg		dsym->s_def = DEF;
175112099Sjoerg
175212099Sjoerg	/*
175312099Sjoerg	 * Declarations of functions are marked as "tentative" in dname().
175412099Sjoerg	 * This is wrong because there are no tentative function
175512099Sjoerg	 * definitions.
175612099Sjoerg	 */
175712099Sjoerg	if (dsym->s_type->t_tspec == FUNC && dsym->s_def == TDEF)
175812099Sjoerg		dsym->s_def = DECL;
175912099Sjoerg
176012099Sjoerg	if (dcs->d_inline) {
176112099Sjoerg		if (dsym->s_type->t_tspec == FUNC) {
176212099Sjoerg			dsym->s_inline = 1;
176312099Sjoerg		} else {
176412099Sjoerg			/* variable declared inline: %s */
176512099Sjoerg			warning(268, dsym->s_name);
176612099Sjoerg		}
176712099Sjoerg	}
176812099Sjoerg
176912099Sjoerg	/* Write the declaration into the output file */
177012099Sjoerg	if (plibflg && llibflg &&
177112099Sjoerg	    dsym->s_type->t_tspec == FUNC && dsym->s_type->t_proto) {
177212099Sjoerg		/*
177312099Sjoerg		 * With both LINTLIBRARY and PROTOLIB the prototyp is
177412099Sjoerg		 * written as a function definition to the output file.
177512099Sjoerg		 */
177612099Sjoerg		rval = dsym->s_type->t_subt->t_tspec != VOID;
177712099Sjoerg		outfdef(dsym, &dsym->s_dpos, rval, 0, NULL);
177812099Sjoerg	} else {
177912099Sjoerg		outsym(dsym, dsym->s_scl, dsym->s_def);
178012099Sjoerg	}
178112099Sjoerg
178212099Sjoerg	if ((rdsym = dcs->d_rdcsym) != NULL) {
178312099Sjoerg
178412099Sjoerg		/*
1785108532Sschweikh		 * If the old symbol stems from an old style function definition
178612099Sjoerg		 * we have remembered the params in rdsmy->s_args and compare
178712099Sjoerg		 * them with the params of the prototype.
178812099Sjoerg		 */
178912099Sjoerg		if (rdsym->s_osdef && dsym->s_type->t_proto) {
179012099Sjoerg			redec = chkosdef(rdsym, dsym);
179112099Sjoerg		} else {
179212099Sjoerg			redec = 0;
179312099Sjoerg		}
179412099Sjoerg
179512099Sjoerg		if (!redec && !isredec(dsym, (warn = 0, &warn))) {
179691592Smarkm
179712099Sjoerg			if (warn) {
179812099Sjoerg				/* redeclaration of %s */
179912099Sjoerg				(*(sflag ? error : warning))(27, dsym->s_name);
180012099Sjoerg				prevdecl(-1, rdsym);
180112099Sjoerg			}
180212099Sjoerg
180312099Sjoerg			/*
180412099Sjoerg			 * Overtake the rememberd params if the new symbol
180512099Sjoerg			 * is not a prototype.
180612099Sjoerg			 */
180712099Sjoerg			if (rdsym->s_osdef && !dsym->s_type->t_proto) {
180812099Sjoerg				dsym->s_osdef = rdsym->s_osdef;
180912099Sjoerg				dsym->s_args = rdsym->s_args;
181012099Sjoerg				STRUCT_ASSIGN(dsym->s_dpos, rdsym->s_dpos);
181112099Sjoerg			}
181212099Sjoerg
181312099Sjoerg			/*
181412099Sjoerg			 * Remember the position of the declaration if the
181512099Sjoerg			 * old symbol was a prototype and the new is not.
181612099Sjoerg			 * Also remember the position if the old symbol
181712099Sjoerg			 * was defined and the new is not.
181812099Sjoerg			 */
181912099Sjoerg			if (rdsym->s_type->t_proto && !dsym->s_type->t_proto) {
182012099Sjoerg				STRUCT_ASSIGN(dsym->s_dpos, rdsym->s_dpos);
182112099Sjoerg			} else if (rdsym->s_def == DEF && dsym->s_def != DEF) {
182212099Sjoerg				STRUCT_ASSIGN(dsym->s_dpos, rdsym->s_dpos);
182312099Sjoerg			}
182412099Sjoerg
182512099Sjoerg			/*
182612099Sjoerg			 * Copy informations about usage of the name into
182712099Sjoerg			 * the new symbol.
182812099Sjoerg			 */
182912099Sjoerg			cpuinfo(dsym, rdsym);
183012099Sjoerg
183112099Sjoerg			/* Once a name is defined, it remains defined. */
183212099Sjoerg			if (rdsym->s_def == DEF)
183312099Sjoerg				dsym->s_def = DEF;
183412099Sjoerg
183512099Sjoerg			/* once a function is inline, it remains inline */
183612099Sjoerg			if (rdsym->s_inline)
183712099Sjoerg				dsym->s_inline = 1;
183812099Sjoerg
183912099Sjoerg			compltyp(dsym, rdsym);
184012099Sjoerg
184112099Sjoerg		}
184291592Smarkm
184312099Sjoerg		rmsym(rdsym);
184412099Sjoerg	}
184512099Sjoerg
184612099Sjoerg	if (dsym->s_scl == TYPEDEF) {
184712099Sjoerg		dsym->s_type = duptyp(dsym->s_type);
184812099Sjoerg		dsym->s_type->t_typedef = 1;
184912099Sjoerg		settdsym(dsym->s_type, dsym);
185012099Sjoerg	}
185112099Sjoerg
185212099Sjoerg}
185312099Sjoerg
185412099Sjoerg/*
185512099Sjoerg * Copies informations about usage into a new symbol table entry of
185612099Sjoerg * the same symbol.
185712099Sjoerg */
185812099Sjoergvoid
185991592Smarkmcpuinfo(sym_t *sym, sym_t *rdsym)
186012099Sjoerg{
186191592Smarkm
186212099Sjoerg	sym->s_spos = rdsym->s_spos;
186312099Sjoerg	sym->s_upos = rdsym->s_upos;
186412099Sjoerg	sym->s_set = rdsym->s_set;
186512099Sjoerg	sym->s_used = rdsym->s_used;
186612099Sjoerg}
186712099Sjoerg
186812099Sjoerg/*
186912099Sjoerg * Prints an error and returns 1 if a symbol is redeclared/redefined.
187012099Sjoerg * Otherwise returns 0 and, in some cases of minor problems, prints
187112099Sjoerg * a warning.
187212099Sjoerg */
187312099Sjoergint
187491592Smarkmisredec(sym_t *dsym, int *warn)
187512099Sjoerg{
187612099Sjoerg	sym_t	*rsym;
187712099Sjoerg
187812099Sjoerg	if ((rsym = dcs->d_rdcsym)->s_scl == ENUMCON) {
187912099Sjoerg		/* redeclaration of %s */
188012099Sjoerg		error(27, dsym->s_name);
188112099Sjoerg		prevdecl(-1, rsym);
188212099Sjoerg		return (1);
188312099Sjoerg	}
188412099Sjoerg	if (rsym->s_scl == TYPEDEF) {
188512099Sjoerg		/* typedef redeclared: %s */
188612099Sjoerg		error(89, dsym->s_name);
188712099Sjoerg		prevdecl(-1, rsym);
188812099Sjoerg		return (1);
188912099Sjoerg	}
189012099Sjoerg	if (dsym->s_scl == TYPEDEF) {
189112099Sjoerg		/* redeclaration of %s */
189212099Sjoerg		error(27, dsym->s_name);
189312099Sjoerg		prevdecl(-1, rsym);
189412099Sjoerg		return (1);
189512099Sjoerg	}
189612099Sjoerg	if (rsym->s_def == DEF && dsym->s_def == DEF) {
189712099Sjoerg		/* redefinition of %s */
189812099Sjoerg		error(28, dsym->s_name);
189912099Sjoerg		prevdecl(-1, rsym);
190012099Sjoerg		return(1);
190112099Sjoerg	}
190212099Sjoerg	if (!eqtype(rsym->s_type, dsym->s_type, 0, 0, warn)) {
190312099Sjoerg		/* redeclaration of %s */
190412099Sjoerg		error(27, dsym->s_name);
190512099Sjoerg		prevdecl(-1, rsym);
190612099Sjoerg		return(1);
190712099Sjoerg	}
190812099Sjoerg	if (rsym->s_scl == EXTERN && dsym->s_scl == EXTERN)
190912099Sjoerg		return(0);
191012099Sjoerg	if (rsym->s_scl == STATIC && dsym->s_scl == STATIC)
191112099Sjoerg		return(0);
191212099Sjoerg	if (rsym->s_scl == STATIC && dsym->s_def == DECL)
191312099Sjoerg		return(0);
191412099Sjoerg	if (rsym->s_scl == EXTERN && rsym->s_def == DEF) {
191512099Sjoerg		/*
191612099Sjoerg		 * All cases except "int a = 1; static int a;" are catched
191712099Sjoerg		 * above with or without a warning
191812099Sjoerg		 */
191912099Sjoerg		/* redeclaration of %s */
192012099Sjoerg		error(27, dsym->s_name);
192112099Sjoerg		prevdecl(-1, rsym);
192212099Sjoerg		return(1);
192312099Sjoerg	}
192412099Sjoerg	if (rsym->s_scl == EXTERN) {
192512099Sjoerg		/* previously declared extern, becomes static: %s */
192612099Sjoerg		warning(29, dsym->s_name);
192712099Sjoerg		prevdecl(-1, rsym);
192812099Sjoerg		return(0);
192912099Sjoerg	}
193012099Sjoerg	/*
193112099Sjoerg	 * Now its on of:
193212099Sjoerg	 * "static a; int a;", "static a; int a = 1;", "static a = 1; int a;"
193312099Sjoerg	 */
193412099Sjoerg	/* redeclaration of %s; ANSI C requires "static" */
193512099Sjoerg	if (sflag) {
193612099Sjoerg		warning(30, dsym->s_name);
193712099Sjoerg		prevdecl(-1, rsym);
193812099Sjoerg	}
193912099Sjoerg	dsym->s_scl = STATIC;
194012099Sjoerg	return (0);
194112099Sjoerg}
194212099Sjoerg
194312099Sjoerg/*
194412099Sjoerg * Checks if two types are compatible. Returns 0 if not, otherwise 1.
194512099Sjoerg *
194612099Sjoerg * ignqual	ignore qualifiers of type; used for function params
194775697Sasmodai * promot	promote left type; used for comparison of params of
194812099Sjoerg *		old style function definitions with params of prototypes.
194912099Sjoerg * *warn	set to 1 if an old style function declaration is not
195012099Sjoerg *		compatible with a prototype
195112099Sjoerg */
195212099Sjoergint
195391592Smarkmeqtype(type_t *tp1, type_t *tp2, int ignqual, int promot, int *warn)
195412099Sjoerg{
195512099Sjoerg	tspec_t	t;
195612099Sjoerg
195712099Sjoerg	while (tp1 != NULL && tp2 != NULL) {
195812099Sjoerg
195912099Sjoerg		t = tp1->t_tspec;
196012099Sjoerg		if (promot) {
196112099Sjoerg			if (t == FLOAT) {
196212099Sjoerg				t = DOUBLE;
196312099Sjoerg			} else if (t == CHAR || t == SCHAR) {
196412099Sjoerg				t = INT;
196512099Sjoerg			} else if (t == UCHAR) {
196612099Sjoerg				t = tflag ? UINT : INT;
196712099Sjoerg			} else if (t == SHORT) {
196812099Sjoerg				t = INT;
196912099Sjoerg			} else if (t == USHORT) {
197012099Sjoerg				/* CONSTCOND */
197112099Sjoerg				t = INT_MAX < USHRT_MAX || tflag ? UINT : INT;
197212099Sjoerg			}
197312099Sjoerg		}
197412099Sjoerg
197512099Sjoerg		if (t != tp2->t_tspec)
197612099Sjoerg			return (0);
197712099Sjoerg
197812099Sjoerg		if (tp1->t_const != tp2->t_const && !ignqual && !tflag)
197912099Sjoerg			return (0);
198012099Sjoerg
198112099Sjoerg		if (tp1->t_volatile != tp2->t_volatile && !ignqual && !tflag)
198212099Sjoerg			return (0);
198312099Sjoerg
198412099Sjoerg		if (t == STRUCT || t == UNION)
198512099Sjoerg			return (tp1->t_str == tp2->t_str);
198612099Sjoerg
198712099Sjoerg		if (t == ARRAY && tp1->t_dim != tp2->t_dim) {
198812099Sjoerg			if (tp1->t_dim != 0 && tp2->t_dim != 0)
198912099Sjoerg				return (0);
199012099Sjoerg		}
199112099Sjoerg
199212099Sjoerg		/* dont check prototypes for traditional */
199312099Sjoerg		if (t == FUNC && !tflag) {
199412099Sjoerg			if (tp1->t_proto && tp2->t_proto) {
199512099Sjoerg				if (!eqargs(tp1, tp2, warn))
199612099Sjoerg					return (0);
199712099Sjoerg			} else if (tp1->t_proto) {
199812099Sjoerg				if (!mnoarg(tp1, warn))
199912099Sjoerg					return (0);
200012099Sjoerg			} else if (tp2->t_proto) {
200112099Sjoerg				if (!mnoarg(tp2, warn))
200212099Sjoerg					return (0);
200312099Sjoerg			}
200412099Sjoerg		}
200512099Sjoerg
200612099Sjoerg		tp1 = tp1->t_subt;
200712099Sjoerg		tp2 = tp2->t_subt;
200812099Sjoerg		ignqual = promot = 0;
200912099Sjoerg
201012099Sjoerg	}
201112099Sjoerg
201212099Sjoerg	return (tp1 == tp2);
201312099Sjoerg}
201412099Sjoerg
201512099Sjoerg/*
201612099Sjoerg * Compares the parameter types of two prototypes.
201712099Sjoerg */
201812099Sjoergstatic int
201991592Smarkmeqargs(type_t *tp1, type_t *tp2, int *warn)
202012099Sjoerg{
202112099Sjoerg	sym_t	*a1, *a2;
202212099Sjoerg
202312099Sjoerg	if (tp1->t_vararg != tp2->t_vararg)
202412099Sjoerg		return (0);
202512099Sjoerg
202612099Sjoerg	a1 = tp1->t_args;
202712099Sjoerg	a2 = tp2->t_args;
202812099Sjoerg
202912099Sjoerg	while (a1 != NULL && a2 != NULL) {
203012099Sjoerg
203112099Sjoerg		if (eqtype(a1->s_type, a2->s_type, 1, 0, warn) == 0)
203212099Sjoerg			return (0);
203312099Sjoerg
203412099Sjoerg		a1 = a1->s_nxt;
203512099Sjoerg		a2 = a2->s_nxt;
203612099Sjoerg
203712099Sjoerg	}
203812099Sjoerg
203912099Sjoerg	return (a1 == a2);
204012099Sjoerg}
204112099Sjoerg
204212099Sjoerg/*
204312099Sjoerg * mnoarg() (matches functions with no argument type information)
204412099Sjoerg * returns 1 if all parameters of a prototype are compatible with
204512099Sjoerg * and old style function declaration.
204612099Sjoerg * This is the case if following conditions are met:
204712099Sjoerg *	1. the prototype must have a fixed number of parameters
204812099Sjoerg *	2. no parameter is of type float
204912099Sjoerg *	3. no parameter is converted to another type if integer promotion
205012099Sjoerg *	   is applied on it
205112099Sjoerg */
205212099Sjoergstatic int
205391592Smarkmmnoarg(type_t *tp, int *warn)
205412099Sjoerg{
205512099Sjoerg	sym_t	*arg;
205612099Sjoerg	tspec_t	t;
205712099Sjoerg
205812099Sjoerg	if (tp->t_vararg) {
205912099Sjoerg		if (warn != NULL)
206012099Sjoerg			*warn = 1;
206112099Sjoerg	}
206212099Sjoerg	for (arg = tp->t_args; arg != NULL; arg = arg->s_nxt) {
206312099Sjoerg		if ((t = arg->s_type->t_tspec) == FLOAT ||
206412099Sjoerg		    t == CHAR || t == SCHAR || t == UCHAR ||
206512099Sjoerg		    t == SHORT || t == USHORT) {
206612099Sjoerg			if (warn != NULL)
206712099Sjoerg				*warn = 1;
206812099Sjoerg		}
206912099Sjoerg	}
207012099Sjoerg	return (1);
207112099Sjoerg}
207212099Sjoerg
207312099Sjoerg/*
207412099Sjoerg * Compares a prototype declaration with the remembered arguments of
207512099Sjoerg * a previous old style function definition.
207612099Sjoerg */
207712099Sjoergstatic int
207891592Smarkmchkosdef(sym_t *rdsym, sym_t *dsym)
207912099Sjoerg{
208012099Sjoerg	sym_t	*args, *pargs, *arg, *parg;
208112099Sjoerg	int	narg, nparg, n;
208212099Sjoerg	int	warn, msg;
208312099Sjoerg
208412099Sjoerg	args = rdsym->s_args;
208512099Sjoerg	pargs = dsym->s_type->t_args;
208612099Sjoerg
208712099Sjoerg	msg = 0;
208812099Sjoerg
208912099Sjoerg	narg = nparg = 0;
209012099Sjoerg	for (arg = args; arg != NULL; arg = arg->s_nxt)
209112099Sjoerg		narg++;
209212099Sjoerg	for (parg = pargs; parg != NULL; parg = parg->s_nxt)
209312099Sjoerg		nparg++;
209412099Sjoerg	if (narg != nparg) {
209512099Sjoerg		/* prototype does not match old-style definition */
209612099Sjoerg		error(63);
209712099Sjoerg		msg = 1;
209812099Sjoerg		goto end;
209912099Sjoerg	}
210012099Sjoerg
210112099Sjoerg	arg = args;
210212099Sjoerg	parg = pargs;
210312099Sjoerg	n = 1;
210412099Sjoerg	while (narg--) {
210512099Sjoerg		warn = 0;
210612099Sjoerg		/*
210712099Sjoerg		 * If it does not match due to promotion and sflag is
210812099Sjoerg		 * not set we print only a warning.
210912099Sjoerg		 */
211012099Sjoerg		if (!eqtype(arg->s_type, parg->s_type, 1, 1, &warn) || warn) {
211112099Sjoerg			/* prototype does not match old-style def., arg #%d */
211212099Sjoerg			error(299, n);
211312099Sjoerg			msg = 1;
211412099Sjoerg		}
211512099Sjoerg		arg = arg->s_nxt;
211612099Sjoerg		parg = parg->s_nxt;
211712099Sjoerg		n++;
211812099Sjoerg	}
211912099Sjoerg
212012099Sjoerg end:
212112099Sjoerg	if (msg)
212212099Sjoerg		/* old style definition */
212312099Sjoerg		prevdecl(300, rdsym);
212412099Sjoerg
212512099Sjoerg	return (msg);
212612099Sjoerg}
212712099Sjoerg
212812099Sjoerg/*
212912099Sjoerg * Complets a type by copying the dimension and prototype information
213012099Sjoerg * from a second compatible type.
213112099Sjoerg *
213212099Sjoerg * Following lines are legal:
213312099Sjoerg *  "typedef a[]; a b; a b[10]; a c; a c[20];"
213412099Sjoerg *  "typedef ft(); ft f; f(int); ft g; g(long);"
213512099Sjoerg * This means that, if a type is completed, the type structure must
213612099Sjoerg * be duplicated.
213712099Sjoerg */
213812099Sjoergvoid
213991592Smarkmcompltyp(sym_t *dsym, sym_t *ssym)
214012099Sjoerg{
214112099Sjoerg	type_t	**dstp, *src;
214212099Sjoerg	type_t	*dst;
214312099Sjoerg
214412099Sjoerg	dstp = &dsym->s_type;
214512099Sjoerg	src = ssym->s_type;
214612099Sjoerg
214712099Sjoerg	while ((dst = *dstp) != NULL) {
214812099Sjoerg		if (src == NULL || dst->t_tspec != src->t_tspec)
214912099Sjoerg			lerror("compltyp() 1");
215012099Sjoerg		if (dst->t_tspec == ARRAY) {
215112099Sjoerg			if (dst->t_dim == 0 && src->t_dim != 0) {
215212099Sjoerg				*dstp = dst = duptyp(dst);
215312099Sjoerg				dst->t_dim = src->t_dim;
215412099Sjoerg				/* now a complete Typ */
215512099Sjoerg				setcompl(dst, 0);
215612099Sjoerg			}
215712099Sjoerg		} else if (dst->t_tspec == FUNC) {
215812099Sjoerg			if (!dst->t_proto && src->t_proto) {
215912099Sjoerg				*dstp = dst = duptyp(dst);
216012099Sjoerg				dst->t_proto = 1;
216112099Sjoerg				dst->t_args = src->t_args;
216212099Sjoerg			}
216312099Sjoerg		}
216412099Sjoerg		dstp = &dst->t_subt;
216512099Sjoerg		src = src->t_subt;
216612099Sjoerg	}
216712099Sjoerg}
216812099Sjoerg
216912099Sjoerg/*
217012099Sjoerg * Completes the declaration of a single argument.
217112099Sjoerg */
217212099Sjoergsym_t *
217391592Smarkmdecl1arg(sym_t *sym, int initflg)
217412099Sjoerg{
217512099Sjoerg	tspec_t	t;
217612099Sjoerg
217712099Sjoerg	chkfdef(sym, 1);
217812099Sjoerg
217912099Sjoerg	chktyp(sym);
218012099Sjoerg
218112099Sjoerg	if (dcs->d_rdcsym != NULL && dcs->d_rdcsym->s_blklev == blklev) {
218212099Sjoerg		/* redeclaration of formal parameter %s */
218312099Sjoerg		error(237, sym->s_name);
218412099Sjoerg		rmsym(dcs->d_rdcsym);
218512099Sjoerg		sym->s_arg = 1;
218612099Sjoerg	}
218712099Sjoerg
218812099Sjoerg	if (!sym->s_arg) {
218912099Sjoerg		/* declared argument %s is missing */
219012099Sjoerg		error(53, sym->s_name);
219112099Sjoerg		sym->s_arg = 1;
219212099Sjoerg	}
219312099Sjoerg
219412099Sjoerg	if (initflg) {
219512099Sjoerg		/* cannot initialize parameter: %s */
219612099Sjoerg		error(52, sym->s_name);
219712099Sjoerg		initerr = 1;
219812099Sjoerg	}
219912099Sjoerg
220012099Sjoerg	if ((t = sym->s_type->t_tspec) == ARRAY) {
220112099Sjoerg		sym->s_type = incref(sym->s_type->t_subt, PTR);
220212099Sjoerg	} else if (t == FUNC) {
220312099Sjoerg		if (tflag)
220412099Sjoerg			/* a function is declared as an argument: %s */
220512099Sjoerg			warning(50, sym->s_name);
220612099Sjoerg		sym->s_type = incref(sym->s_type, PTR);
220712099Sjoerg	} else if (t == FLOAT) {
220812099Sjoerg		if (tflag)
220912099Sjoerg			sym->s_type = gettyp(DOUBLE);
221012099Sjoerg	}
221112099Sjoerg
221212099Sjoerg	if (dcs->d_inline)
221312099Sjoerg		/* argument declared inline: %s */
221412099Sjoerg		warning(269, sym->s_name);
221512099Sjoerg
221612099Sjoerg	/*
221712099Sjoerg	 * Arguments must have complete types. lengths() prints the needed
221812099Sjoerg	 * error messages (null dimension is impossible because arrays are
221912099Sjoerg	 * converted to pointers).
222012099Sjoerg	 */
222112099Sjoerg	if (sym->s_type->t_tspec != VOID)
222212099Sjoerg		(void)length(sym->s_type, sym->s_name);
222312099Sjoerg
222412099Sjoerg	setsflg(sym);
222512099Sjoerg
222612099Sjoerg	return (sym);
222712099Sjoerg}
222812099Sjoerg
222912099Sjoerg/*
223012099Sjoerg * Does some checks for lint directives which apply to functions.
223112099Sjoerg * Processes arguments in old style function definitions which default
223212099Sjoerg * to int.
223312099Sjoerg * Checks compatiblility of old style function definition with previous
223412099Sjoerg * prototype.
223512099Sjoerg */
223612099Sjoergvoid
223791592Smarkmcluparg(void)
223812099Sjoerg{
223912099Sjoerg	sym_t	*args, *arg, *pargs, *parg;
224012099Sjoerg	int	narg, nparg, n, msg;
224112099Sjoerg	tspec_t	t;
224212099Sjoerg
224312099Sjoerg	args = funcsym->s_args;
224412099Sjoerg	pargs = funcsym->s_type->t_args;
224512099Sjoerg
224612099Sjoerg	/* check for illegal combinations of lint directives */
224712099Sjoerg	if (prflstrg != -1 && scflstrg != -1) {
224812099Sjoerg		/* can't be used together: ** PRINTFLIKE ** ** SCANFLIKE ** */
224912099Sjoerg		warning(289);
225012099Sjoerg		prflstrg = scflstrg = -1;
225112099Sjoerg	}
225212099Sjoerg	if (nvararg != -1 && (prflstrg != -1 || scflstrg != -1)) {
225312099Sjoerg		/* dubious use of ** VARARGS ** with ** %s ** */
225412099Sjoerg		warning(288, prflstrg != -1 ? "PRINTFLIKE" : "SCANFLIKE");
225512099Sjoerg		nvararg = -1;
225612099Sjoerg	}
225712099Sjoerg
225812099Sjoerg	/*
225912099Sjoerg	 * check if the argument of a lint directive is compatible with the
226012099Sjoerg	 * number of arguments.
226112099Sjoerg	 */
226212099Sjoerg	narg = 0;
226312099Sjoerg	for (arg = dcs->d_fargs; arg != NULL; arg = arg->s_nxt)
226412099Sjoerg		narg++;
226512099Sjoerg	if (nargusg > narg) {
226612099Sjoerg		/* argument number mismatch with directive: ** %s ** */
226712099Sjoerg		warning(283, "ARGSUSED");
226812099Sjoerg		nargusg = 0;
226912099Sjoerg	}
227012099Sjoerg	if (nvararg > narg) {
227112099Sjoerg		/* argument number mismatch with directive: ** %s ** */
227212099Sjoerg		warning(283, "VARARGS");
227312099Sjoerg		nvararg = 0;
227412099Sjoerg	}
227512099Sjoerg	if (prflstrg > narg) {
227612099Sjoerg		/* argument number mismatch with directive: ** %s ** */
227712099Sjoerg		warning(283, "PRINTFLIKE");
227812099Sjoerg		prflstrg = -1;
227912099Sjoerg	} else if (prflstrg == 0) {
228012099Sjoerg		prflstrg = -1;
228112099Sjoerg	}
228212099Sjoerg	if (scflstrg > narg) {
228312099Sjoerg		/* argument number mismatch with directive: ** %s ** */
228412099Sjoerg		warning(283, "SCANFLIKE");
228512099Sjoerg		scflstrg = -1;
228612099Sjoerg	} else if (scflstrg == 0) {
228712099Sjoerg		scflstrg = -1;
228812099Sjoerg	}
228912099Sjoerg	if (prflstrg != -1 || scflstrg != -1) {
229012099Sjoerg		narg = prflstrg != -1 ? prflstrg : scflstrg;
229112099Sjoerg		arg = dcs->d_fargs;
229212099Sjoerg		for (n = 1; n < narg; n++)
229312099Sjoerg			arg = arg->s_nxt;
229412099Sjoerg		if (arg->s_type->t_tspec != PTR ||
229512099Sjoerg		    ((t = arg->s_type->t_subt->t_tspec) != CHAR &&
229612099Sjoerg		     t != UCHAR && t != SCHAR)) {
229712099Sjoerg			/* arg. %d must be 'char *' for PRINTFLIKE/SCANFLIKE */
229812099Sjoerg			warning(293, narg);
229912099Sjoerg			prflstrg = scflstrg = -1;
230012099Sjoerg		}
230112099Sjoerg	}
230212099Sjoerg
230312099Sjoerg	/*
230412099Sjoerg	 * print a warning for each argument off an old style function
230512099Sjoerg	 * definition which defaults to int
230612099Sjoerg	 */
230712099Sjoerg	for (arg = args; arg != NULL; arg = arg->s_nxt) {
230812099Sjoerg		if (arg->s_defarg) {
230912099Sjoerg			/* argument type defaults to int: %s */
231012099Sjoerg			warning(32, arg->s_name);
231112099Sjoerg			arg->s_defarg = 0;
231212099Sjoerg			setsflg(arg);
231312099Sjoerg		}
231412099Sjoerg	}
231512099Sjoerg
231612099Sjoerg	/*
231712099Sjoerg	 * If this is an old style function definition and a prototyp
231812099Sjoerg	 * exists, compare the types of arguments.
231912099Sjoerg	 */
232012099Sjoerg	if (funcsym->s_osdef && funcsym->s_type->t_proto) {
232112099Sjoerg		/*
232212099Sjoerg		 * If the number of arguments does not macht, we need not
232312099Sjoerg		 * continue.
232412099Sjoerg		 */
232512099Sjoerg		narg = nparg = 0;
232612099Sjoerg		msg = 0;
232712099Sjoerg		for (parg = pargs; parg != NULL; parg = parg->s_nxt)
232812099Sjoerg			nparg++;
232912099Sjoerg		for (arg = args; arg != NULL; arg = arg->s_nxt)
233012099Sjoerg			narg++;
233112099Sjoerg		if (narg != nparg) {
233212099Sjoerg			/* parameter mismatch: %d declared, %d defined */
233312099Sjoerg			error(51, nparg, narg);
233412099Sjoerg			msg = 1;
233512099Sjoerg		} else {
233612099Sjoerg			parg = pargs;
233712099Sjoerg			arg = args;
233812099Sjoerg			while (narg--) {
233912099Sjoerg				msg |= chkptdecl(arg, parg);
234012099Sjoerg				parg = parg->s_nxt;
234112099Sjoerg				arg = arg->s_nxt;
234212099Sjoerg			}
234312099Sjoerg		}
234412099Sjoerg		if (msg)
234512099Sjoerg			/* prototype declaration */
234612099Sjoerg			prevdecl(285, dcs->d_rdcsym);
234712099Sjoerg
234812099Sjoerg		/* from now the prototype is valid */
234912099Sjoerg		funcsym->s_osdef = 0;
235012099Sjoerg		funcsym->s_args = NULL;
235191592Smarkm
235212099Sjoerg	}
235312099Sjoerg
235412099Sjoerg}
235512099Sjoerg
235612099Sjoerg/*
235712099Sjoerg * Checks compatibility of an old style function definition with a previous
235812099Sjoerg * prototype declaration.
235912099Sjoerg * Returns 1 if the position of the previous declaration should be reported.
236012099Sjoerg */
236112099Sjoergstatic int
236291592Smarkmchkptdecl(sym_t *arg, sym_t *parg)
236312099Sjoerg{
236412099Sjoerg	type_t	*tp, *ptp;
236512099Sjoerg	int	warn, msg;
236612099Sjoerg
236712099Sjoerg	tp = arg->s_type;
236812099Sjoerg	ptp = parg->s_type;
236912099Sjoerg
237012099Sjoerg	msg = 0;
237112099Sjoerg	warn = 0;
237212099Sjoerg
237312099Sjoerg	if (!eqtype(tp, ptp, 1, 1, &warn)) {
237412099Sjoerg		if (eqtype(tp, ptp, 1, 0, &warn)) {
237512099Sjoerg			/* type does not match prototype: %s */
237612099Sjoerg			msg = gnuism(58, arg->s_name);
237712099Sjoerg		} else {
237812099Sjoerg			/* type does not match prototype: %s */
237912099Sjoerg			error(58, arg->s_name);
238012099Sjoerg			msg = 1;
238112099Sjoerg		}
238212099Sjoerg	} else if (warn) {
238312099Sjoerg		/* type does not match prototype: %s */
238412099Sjoerg		(*(sflag ? error : warning))(58, arg->s_name);
238512099Sjoerg		msg = 1;
238612099Sjoerg	}
238712099Sjoerg
238812099Sjoerg	return (msg);
238912099Sjoerg}
239012099Sjoerg
239112099Sjoerg/*
239212099Sjoerg * Completes a single local declaration/definition.
239312099Sjoerg */
239412099Sjoergvoid
239591592Smarkmdecl1loc(sym_t *dsym, int initflg)
239612099Sjoerg{
239791592Smarkm
239812099Sjoerg	/* Correct a mistake done in dname(). */
239912099Sjoerg	if (dsym->s_type->t_tspec == FUNC) {
240012099Sjoerg		dsym->s_def = DECL;
240112099Sjoerg		if (dcs->d_scl == NOSCL)
240212099Sjoerg			dsym->s_scl = EXTERN;
240312099Sjoerg	}
240412099Sjoerg
240512099Sjoerg	if (dsym->s_type->t_tspec == FUNC) {
240612099Sjoerg		if (dsym->s_scl == STATIC) {
240712099Sjoerg			/* dubious static function at block level: %s */
240812099Sjoerg			warning(93, dsym->s_name);
240912099Sjoerg			dsym->s_scl = EXTERN;
241012099Sjoerg		} else if (dsym->s_scl != EXTERN && dsym->s_scl != TYPEDEF) {
241112099Sjoerg			/* function has illegal storage class: %s */
241212099Sjoerg			error(94, dsym->s_name);
241312099Sjoerg			dsym->s_scl = EXTERN;
241412099Sjoerg		}
241512099Sjoerg	}
241612099Sjoerg
241712099Sjoerg	/*
241812099Sjoerg	 * functions may be declared inline at local scope, although
241912099Sjoerg	 * this has no effect for a later definition of the same
242012099Sjoerg	 * function.
242112099Sjoerg	 * XXX it should have an effect if tflag is set. this would
242212099Sjoerg	 * also be the way gcc behaves.
242312099Sjoerg	 */
242412099Sjoerg	if (dcs->d_inline) {
242512099Sjoerg		if (dsym->s_type->t_tspec == FUNC) {
242612099Sjoerg			dsym->s_inline = 1;
242712099Sjoerg		} else {
242812099Sjoerg			/* variable declared inline: %s */
242912099Sjoerg			warning(268, dsym->s_name);
243012099Sjoerg		}
243112099Sjoerg	}
243212099Sjoerg
243312099Sjoerg	chkfdef(dsym, 1);
243412099Sjoerg
243512099Sjoerg	chktyp(dsym);
243612099Sjoerg
243712099Sjoerg	if (dcs->d_rdcsym != NULL && dsym->s_scl == EXTERN)
243812099Sjoerg		ledecl(dsym);
243912099Sjoerg
244012099Sjoerg	if (dsym->s_scl == EXTERN) {
244112099Sjoerg		/*
244212099Sjoerg		 * XXX wenn die statische Variable auf Ebene 0 erst
244312099Sjoerg		 * spaeter definiert wird, haben wir die Brille auf.
244412099Sjoerg		 */
244512099Sjoerg		if (dsym->s_xsym == NULL) {
244612099Sjoerg			outsym(dsym, EXTERN, dsym->s_def);
244712099Sjoerg		} else {
244812099Sjoerg			outsym(dsym, dsym->s_xsym->s_scl, dsym->s_def);
244912099Sjoerg		}
245012099Sjoerg	}
245112099Sjoerg
245212099Sjoerg	if (dcs->d_rdcsym != NULL) {
245312099Sjoerg
245412099Sjoerg		if (dcs->d_rdcsym->s_blklev == 0) {
245512099Sjoerg
245612099Sjoerg			switch (dsym->s_scl) {
245712099Sjoerg			case AUTO:
245812099Sjoerg				/* automatic hides external declaration: %s */
245912099Sjoerg				if (hflag)
246012099Sjoerg					warning(86, dsym->s_name);
246112099Sjoerg				break;
246212099Sjoerg			case STATIC:
246312099Sjoerg				/* static hides external declaration: %s */
246412099Sjoerg				if (hflag)
246512099Sjoerg					warning(87, dsym->s_name);
246612099Sjoerg				break;
246712099Sjoerg			case TYPEDEF:
246812099Sjoerg				/* typedef hides  external declaration: %s */
246912099Sjoerg				if (hflag)
247012099Sjoerg					warning(88, dsym->s_name);
247112099Sjoerg				break;
247212099Sjoerg			case EXTERN:
247312099Sjoerg				/*
247412099Sjoerg				 * Warnings and errors are printed in ledecl()
247512099Sjoerg				 */
247612099Sjoerg				break;
247712099Sjoerg			default:
247812099Sjoerg				lerror("decl1loc() 1");
247912099Sjoerg			}
248012099Sjoerg
248112099Sjoerg		} else if (dcs->d_rdcsym->s_blklev == blklev) {
248212099Sjoerg
248312099Sjoerg			/* no hflag, because its illegal! */
248412099Sjoerg			if (dcs->d_rdcsym->s_arg) {
248512099Sjoerg				/*
248612099Sjoerg				 * if !tflag, a "redeclaration of %s" error
248712099Sjoerg				 * is produced below
248812099Sjoerg				 */
248912099Sjoerg				if (tflag) {
249012099Sjoerg					if (hflag)
249112099Sjoerg						/* decl. hides parameter: %s */
249212099Sjoerg						warning(91, dsym->s_name);
249312099Sjoerg					rmsym(dcs->d_rdcsym);
249412099Sjoerg				}
249512099Sjoerg			}
249612099Sjoerg
249712099Sjoerg		} else if (dcs->d_rdcsym->s_blklev < blklev) {
249812099Sjoerg
249912099Sjoerg			if (hflag)
250012099Sjoerg				/* declaration hides earlier one: %s */
250112099Sjoerg				warning(95, dsym->s_name);
250291592Smarkm
250312099Sjoerg		}
250412099Sjoerg
250512099Sjoerg		if (dcs->d_rdcsym->s_blklev == blklev) {
250612099Sjoerg
250712099Sjoerg			/* redeclaration of %s */
250812099Sjoerg			error(27, dsym->s_name);
250912099Sjoerg			rmsym(dcs->d_rdcsym);
251012099Sjoerg
251112099Sjoerg		}
251212099Sjoerg
251312099Sjoerg	}
251412099Sjoerg
251512099Sjoerg	if (initflg && !(initerr = chkinit(dsym))) {
251612099Sjoerg		dsym->s_def = DEF;
251712099Sjoerg		setsflg(dsym);
251812099Sjoerg	}
251912099Sjoerg
252012099Sjoerg	if (dsym->s_scl == TYPEDEF) {
252112099Sjoerg		dsym->s_type = duptyp(dsym->s_type);
252212099Sjoerg		dsym->s_type->t_typedef = 1;
252312099Sjoerg		settdsym(dsym->s_type, dsym);
252412099Sjoerg	}
252512099Sjoerg
252612099Sjoerg	/*
2527108532Sschweikh	 * Before we can check the size we must wait for an initialisation
252812099Sjoerg	 * which may follow.
252912099Sjoerg	 */
253012099Sjoerg}
253112099Sjoerg
253212099Sjoerg/*
253312099Sjoerg * Processes (re)declarations of external Symbols inside blocks.
253412099Sjoerg */
253512099Sjoergstatic void
253691592Smarkmledecl(sym_t *dsym)
253712099Sjoerg{
253812099Sjoerg	int	eqt, warn;
253912099Sjoerg	sym_t	*esym;
254012099Sjoerg
254112099Sjoerg	/* look for a symbol with the same name */
254212099Sjoerg	esym = dcs->d_rdcsym;
254312099Sjoerg	while (esym != NULL && esym->s_blklev != 0) {
254412099Sjoerg		while ((esym = esym->s_link) != NULL) {
254512099Sjoerg			if (esym->s_kind != FVFT)
254612099Sjoerg				continue;
254712099Sjoerg			if (strcmp(dsym->s_name, esym->s_name) == 0)
254812099Sjoerg				break;
254912099Sjoerg		}
255012099Sjoerg	}
255112099Sjoerg	if (esym == NULL)
255212099Sjoerg		return;
255312099Sjoerg	if (esym->s_scl != EXTERN && esym->s_scl != STATIC) {
255412099Sjoerg		/* gcc accepts this without a warning, pcc prints an error. */
255512099Sjoerg		/* redeclaration of %s */
255612099Sjoerg		warning(27, dsym->s_name);
255712099Sjoerg		prevdecl(-1, esym);
255812099Sjoerg		return;
255912099Sjoerg	}
256012099Sjoerg
256112099Sjoerg	warn = 0;
256212099Sjoerg	eqt = eqtype(esym->s_type, dsym->s_type, 0, 0, &warn);
256312099Sjoerg
256412099Sjoerg	if (!eqt || warn) {
256512099Sjoerg		if (esym->s_scl == EXTERN) {
256612099Sjoerg			/* inconsistent redeclaration of extern: %s */
256712099Sjoerg			warning(90, dsym->s_name);
256812099Sjoerg			prevdecl(-1, esym);
256912099Sjoerg		} else {
257012099Sjoerg			/* inconsistent redeclaration of static: %s */
257112099Sjoerg			warning(92, dsym->s_name);
257212099Sjoerg			prevdecl(-1, esym);
257312099Sjoerg		}
257412099Sjoerg	}
257512099Sjoerg
257612099Sjoerg	if (eqt) {
257712099Sjoerg		/*
257812099Sjoerg		 * Remember the external symbol so we can update usage
257912099Sjoerg		 * information at the end of the block.
258012099Sjoerg		 */
258112099Sjoerg		dsym->s_xsym = esym;
258212099Sjoerg	}
258312099Sjoerg}
258412099Sjoerg
258512099Sjoerg/*
258612099Sjoerg * Print an error or a warning if the symbol cant be initialized due
258712099Sjoerg * to type/storage class. Returnvalue is 1 if an error has been
258812099Sjoerg * detected.
258912099Sjoerg */
259012099Sjoergstatic int
259191592Smarkmchkinit(sym_t *sym)
259212099Sjoerg{
259312099Sjoerg	int	err;
259412099Sjoerg
259512099Sjoerg	err = 0;
259612099Sjoerg
259712099Sjoerg	if (sym->s_type->t_tspec == FUNC) {
259812099Sjoerg		/* cannot initialize function: %s */
259912099Sjoerg		error(24, sym->s_name);
260012099Sjoerg		err = 1;
260112099Sjoerg	} else if (sym->s_scl == TYPEDEF) {
260212099Sjoerg		/* cannot initialize typedef: %s */
260312099Sjoerg		error(25, sym->s_name);
260412099Sjoerg		err = 1;
260512099Sjoerg	} else if (sym->s_scl == EXTERN && sym->s_def == DECL) {
260612099Sjoerg		/* cannot initialize "extern" declaration: %s */
260712099Sjoerg		if (dcs->d_ctx == EXTERN) {
260812099Sjoerg			warning(26, sym->s_name);
260912099Sjoerg		} else {
261012099Sjoerg			error(26, sym->s_name);
261112099Sjoerg			err = 1;
261212099Sjoerg		}
261312099Sjoerg	}
261412099Sjoerg
261512099Sjoerg	return (err);
261612099Sjoerg}
261712099Sjoerg
261812099Sjoerg/*
261912099Sjoerg * Create a symbole for an abstract declaration.
262012099Sjoerg */
262112099Sjoergsym_t *
262291592Smarkmaname(void)
262312099Sjoerg{
262412099Sjoerg	sym_t	*sym;
262512099Sjoerg
262612099Sjoerg	if (dcs->d_ctx != ABSTRACT && dcs->d_ctx != PARG)
262712099Sjoerg		lerror("aname()");
262812099Sjoerg
262912099Sjoerg	sym = getblk(sizeof (sym_t));
263012099Sjoerg
263112099Sjoerg	sym->s_name = unnamed;
263212099Sjoerg	sym->s_def = DEF;
263312099Sjoerg	sym->s_scl = ABSTRACT;
263412099Sjoerg	sym->s_blklev = -1;
263512099Sjoerg
263612099Sjoerg	if (dcs->d_ctx == PARG)
263712099Sjoerg		sym->s_arg = 1;
263812099Sjoerg
263912099Sjoerg	sym->s_type = dcs->d_type;
264012099Sjoerg	dcs->d_rdcsym = NULL;
264112099Sjoerg	dcs->d_vararg = 0;
264212099Sjoerg
264312099Sjoerg	return (sym);
264412099Sjoerg}
264512099Sjoerg
264612099Sjoerg/*
264712099Sjoerg * Removes anything which has nothing to do on global level.
264812099Sjoerg */
264912099Sjoergvoid
265091592Smarkmglobclup(void)
265112099Sjoerg{
265291592Smarkm
265312099Sjoerg	while (dcs->d_nxt != NULL)
265412099Sjoerg		popdecl();
265512099Sjoerg
265612099Sjoerg	cleanup();
265712099Sjoerg	blklev = 0;
265812099Sjoerg	mblklev = 0;
265912099Sjoerg
266012099Sjoerg	/*
266112099Sjoerg	 * remove all informations about pending lint directives without
266212099Sjoerg	 * warnings.
266312099Sjoerg	 */
266412099Sjoerg	glclup(1);
266512099Sjoerg}
266612099Sjoerg
266712099Sjoerg/*
266812099Sjoerg * Process an abstract type declaration
266912099Sjoerg */
267012099Sjoergsym_t *
267191592Smarkmdecl1abs(sym_t *sym)
267212099Sjoerg{
267391592Smarkm
267412099Sjoerg	chkfdef(sym, 1);
267512099Sjoerg	chktyp(sym);
267612099Sjoerg	return (sym);
267712099Sjoerg}
267812099Sjoerg
267912099Sjoerg/*
268012099Sjoerg * Checks size after declarations of variables and their initialisation.
268112099Sjoerg */
268212099Sjoergvoid
268391592Smarkmchksz(sym_t *dsym)
268412099Sjoerg{
268591592Smarkm
268612099Sjoerg	/*
268712099Sjoerg	 * check size only for symbols which are defined and no function and
268812099Sjoerg	 * not typedef name
268912099Sjoerg	 */
269012099Sjoerg	if (dsym->s_def != DEF)
269112099Sjoerg		return;
269212099Sjoerg	if (dsym->s_scl == TYPEDEF)
269312099Sjoerg		return;
269412099Sjoerg	if (dsym->s_type->t_tspec == FUNC)
269512099Sjoerg		return;
269612099Sjoerg
269712099Sjoerg	if (length(dsym->s_type, dsym->s_name) == 0 &&
269812099Sjoerg	    dsym->s_type->t_tspec == ARRAY && dsym->s_type->t_dim == 0) {
269912099Sjoerg		/* empty array declaration: %s */
270012099Sjoerg		if (tflag) {
270112099Sjoerg			warning(190, dsym->s_name);
270212099Sjoerg		} else {
270312099Sjoerg			error(190, dsym->s_name);
270412099Sjoerg		}
270512099Sjoerg	}
270612099Sjoerg}
270712099Sjoerg
270812099Sjoerg/*
270912099Sjoerg * Mark an object as set if it is not already
271012099Sjoerg */
271112099Sjoergvoid
271291592Smarkmsetsflg(sym_t *sym)
271312099Sjoerg{
271491592Smarkm
271512099Sjoerg	if (!sym->s_set) {
271612099Sjoerg		sym->s_set = 1;
271791592Smarkm		UNIQUE_CURR_POS(sym->s_spos);
271812099Sjoerg	}
271912099Sjoerg}
272012099Sjoerg
272112099Sjoerg/*
272212099Sjoerg * Mark an object as used if it is not already
272312099Sjoerg */
272412099Sjoergvoid
272591592Smarkmsetuflg(sym_t *sym, int fcall, int szof)
272612099Sjoerg{
272791592Smarkm
272812099Sjoerg	if (!sym->s_used) {
272912099Sjoerg		sym->s_used = 1;
273091592Smarkm		UNIQUE_CURR_POS(sym->s_upos);
273112099Sjoerg	}
273212099Sjoerg	/*
273312099Sjoerg	 * for function calls another record is written
273412099Sjoerg	 *
273512099Sjoerg	 * XXX Should symbols used in sizeof() treated as used or not?
273612099Sjoerg	 * Probably not, because there is no sense to declare an
273712099Sjoerg	 * external variable only to get their size.
273812099Sjoerg	 */
273912099Sjoerg	if (!fcall && !szof && sym->s_kind == FVFT && sym->s_scl == EXTERN)
274012099Sjoerg		outusg(sym);
274112099Sjoerg}
274212099Sjoerg
274312099Sjoerg/*
274412099Sjoerg * Prints warnings for a list of variables and labels (concatenated
274512099Sjoerg * with s_dlnxt) if these are not used or only set.
274612099Sjoerg */
274712099Sjoergvoid
274891592Smarkmchkusage(dinfo_t *di)
274912099Sjoerg{
275012099Sjoerg	sym_t	*sym;
275112099Sjoerg	int	mknowarn;
275212099Sjoerg
275312099Sjoerg	/* for this warnings LINTED has no effect */
275412099Sjoerg	mknowarn = nowarn;
275512099Sjoerg	nowarn = 0;
275612099Sjoerg
275712099Sjoerg	for (sym = di->d_dlsyms; sym != NULL; sym = sym->s_dlnxt)
275812099Sjoerg		chkusg1(di->d_asm, sym);
275912099Sjoerg
276012099Sjoerg	nowarn = mknowarn;
276112099Sjoerg}
276212099Sjoerg
276312099Sjoerg/*
276412099Sjoerg * Prints a warning for a single variable or label if it is not used or
276512099Sjoerg * only set.
276612099Sjoerg */
276712099Sjoergvoid
276891592Smarkmchkusg1(int novar, sym_t *sym)
276912099Sjoerg{
277012099Sjoerg	pos_t	cpos;
277112099Sjoerg
277212099Sjoerg	if (sym->s_blklev == -1)
277312099Sjoerg		return;
277412099Sjoerg
277512099Sjoerg	STRUCT_ASSIGN(cpos, curr_pos);
277612099Sjoerg
277712099Sjoerg	if (sym->s_kind == FVFT) {
277812099Sjoerg		if (sym->s_arg) {
277912099Sjoerg			chkausg(novar, sym);
278012099Sjoerg		} else {
278112099Sjoerg			chkvusg(novar, sym);
278212099Sjoerg		}
278312099Sjoerg	} else if (sym->s_kind == FLAB) {
278412099Sjoerg		chklusg(sym);
278512099Sjoerg	} else if (sym->s_kind == FTAG) {
278612099Sjoerg		chktusg(sym);
278712099Sjoerg	}
278812099Sjoerg
278912099Sjoerg	STRUCT_ASSIGN(curr_pos, cpos);
279012099Sjoerg}
279112099Sjoerg
279212099Sjoergstatic void
279391592Smarkmchkausg(int novar, sym_t *arg)
279412099Sjoerg{
279591592Smarkm
279612099Sjoerg	if (!arg->s_set)
279712099Sjoerg		lerror("chkausg() 1");
279812099Sjoerg
279912099Sjoerg	if (novar)
280012099Sjoerg		return;
280112099Sjoerg
280212099Sjoerg	if (!arg->s_used && vflag) {
280312099Sjoerg		STRUCT_ASSIGN(curr_pos, arg->s_dpos);
280412099Sjoerg		/* argument %s unused in function %s */
280512099Sjoerg		warning(231, arg->s_name, funcsym->s_name);
280612099Sjoerg	}
280712099Sjoerg}
280812099Sjoerg
280912099Sjoergstatic void
281091592Smarkmchkvusg(int novar, sym_t *sym)
281112099Sjoerg{
281212099Sjoerg	scl_t	sc;
281312099Sjoerg	sym_t	*xsym;
281412099Sjoerg
281512099Sjoerg	if (blklev == 0 || sym->s_blklev == 0)
281612099Sjoerg		lerror("chkvusg() 1");
281712099Sjoerg
281812099Sjoerg	/* errors in expressions easily cause lots of these warnings */
281912099Sjoerg	if (nerr != 0)
282012099Sjoerg		return;
282112099Sjoerg
282212099Sjoerg	/*
282312099Sjoerg	 * XXX Only variables are checkd, although types should
282412099Sjoerg	 * probably also be checked
282512099Sjoerg	 */
282612099Sjoerg	if ((sc = sym->s_scl) != EXTERN && sc != STATIC &&
282712099Sjoerg	    sc != AUTO && sc != REG) {
282812099Sjoerg		return;
282912099Sjoerg	}
283012099Sjoerg
283112099Sjoerg	if (novar)
283212099Sjoerg		return;
283312099Sjoerg
283412099Sjoerg	if (sc == EXTERN) {
283512099Sjoerg		if (!sym->s_used && !sym->s_set) {
283612099Sjoerg			STRUCT_ASSIGN(curr_pos, sym->s_dpos);
283712099Sjoerg			/* %s unused in function %s */
283812099Sjoerg			warning(192, sym->s_name, funcsym->s_name);
283912099Sjoerg		}
284012099Sjoerg	} else {
284112099Sjoerg		if (sym->s_set && !sym->s_used) {
284212099Sjoerg			STRUCT_ASSIGN(curr_pos, sym->s_spos);
284312099Sjoerg			/* %s set but not used in function %s */
284412099Sjoerg			warning(191, sym->s_name, funcsym->s_name);
284512099Sjoerg		} else if (!sym->s_used) {
284612099Sjoerg			STRUCT_ASSIGN(curr_pos, sym->s_dpos);
284712099Sjoerg			/* %s unused in function %s */
284812099Sjoerg			warning(192, sym->s_name, funcsym->s_name);
284912099Sjoerg		}
285012099Sjoerg	}
285112099Sjoerg
285212099Sjoerg	if (sc == EXTERN) {
285312099Sjoerg		/*
285412099Sjoerg		 * information about usage is taken over into the symbol
285512099Sjoerg		 * tabel entry at level 0 if the symbol was locally declared
285612099Sjoerg		 * as an external symbol.
285712099Sjoerg		 *
285812099Sjoerg		 * XXX This is wrong for symbols declared static at level 0
285912099Sjoerg		 * if the usage information stems from sizeof(). This is
286012099Sjoerg		 * because symbols at level 0 only used in sizeof() are
286112099Sjoerg		 * considered to not be used.
286212099Sjoerg		 */
286312099Sjoerg		if ((xsym = sym->s_xsym) != NULL) {
286412099Sjoerg			if (sym->s_used && !xsym->s_used) {
286512099Sjoerg				xsym->s_used = 1;
286612099Sjoerg				STRUCT_ASSIGN(xsym->s_upos, sym->s_upos);
286712099Sjoerg			}
286812099Sjoerg			if (sym->s_set && !xsym->s_set) {
286912099Sjoerg				xsym->s_set = 1;
287012099Sjoerg				STRUCT_ASSIGN(xsym->s_spos, sym->s_spos);
287112099Sjoerg			}
287212099Sjoerg		}
287312099Sjoerg	}
287412099Sjoerg}
287512099Sjoerg
287612099Sjoergstatic void
287791592Smarkmchklusg(sym_t *lab)
287812099Sjoerg{
287991592Smarkm
288012099Sjoerg	if (blklev != 1 || lab->s_blklev != 1)
288112099Sjoerg		lerror("chklusg() 1");
288212099Sjoerg
288312099Sjoerg	if (lab->s_set && !lab->s_used) {
288412099Sjoerg		STRUCT_ASSIGN(curr_pos, lab->s_spos);
288512099Sjoerg		/* label %s unused in function %s */
288612099Sjoerg		warning(192, lab->s_name, funcsym->s_name);
288712099Sjoerg	} else if (!lab->s_set) {
288812099Sjoerg		STRUCT_ASSIGN(curr_pos, lab->s_upos);
288912099Sjoerg		/* undefined label %s */
289012099Sjoerg		warning(23, lab->s_name);
289112099Sjoerg	}
289212099Sjoerg}
289312099Sjoerg
289412099Sjoergstatic void
289591592Smarkmchktusg(sym_t *sym)
289612099Sjoerg{
289791592Smarkm
289812099Sjoerg	if (!incompl(sym->s_type))
289912099Sjoerg		return;
290012099Sjoerg
290112099Sjoerg	/* complain alwasy about incomplet tags declared inside blocks */
290212099Sjoerg	if (!zflag || dcs->d_ctx != EXTERN)
290312099Sjoerg		return;
290412099Sjoerg
290512099Sjoerg	STRUCT_ASSIGN(curr_pos, sym->s_dpos);
290612099Sjoerg	switch (sym->s_type->t_tspec) {
290712099Sjoerg	case STRUCT:
290812099Sjoerg		/* struct %s never defined */
290912099Sjoerg		warning(233, sym->s_name);
291012099Sjoerg		break;
291112099Sjoerg	case UNION:
291212099Sjoerg		/* union %s never defined */
291312099Sjoerg		warning(234, sym->s_name);
291412099Sjoerg		break;
291512099Sjoerg	case ENUM:
291612099Sjoerg		/* enum %s never defined */
291712099Sjoerg		warning(235, sym->s_name);
291812099Sjoerg		break;
291912099Sjoerg	default:
292012099Sjoerg		lerror("chktusg() 1");
292112099Sjoerg	}
292212099Sjoerg}
292312099Sjoerg
292412099Sjoerg/*
292512099Sjoerg * Called after the entire translation unit has been parsed.
292612099Sjoerg * Changes tentative definitions in definitions.
292712099Sjoerg * Performs some tests on global Symbols. Detected Problems are:
292812099Sjoerg * - defined variables of incomplete type
292912099Sjoerg * - constant variables which are not initialized
293012099Sjoerg * - static symbols which are never used
293112099Sjoerg */
293212099Sjoergvoid
293391592Smarkmchkglsyms(void)
293412099Sjoerg{
293512099Sjoerg	sym_t	*sym;
293612099Sjoerg	pos_t	cpos;
293712099Sjoerg
293812099Sjoerg	if (blklev != 0 || dcs->d_nxt != NULL)
293912099Sjoerg		norecover();
294012099Sjoerg
294112099Sjoerg	STRUCT_ASSIGN(cpos, curr_pos);
294212099Sjoerg
294312099Sjoerg	for (sym = dcs->d_dlsyms; sym != NULL; sym = sym->s_dlnxt) {
294412099Sjoerg		if (sym->s_blklev == -1)
294512099Sjoerg			continue;
294612099Sjoerg		if (sym->s_kind == FVFT) {
294712099Sjoerg			chkglvar(sym);
294812099Sjoerg		} else if (sym->s_kind == FTAG) {
294912099Sjoerg			chktusg(sym);
295012099Sjoerg		} else {
295112099Sjoerg			if (sym->s_kind != FMOS)
295212099Sjoerg				lerror("chkglsyms() 1");
295312099Sjoerg		}
295412099Sjoerg	}
295512099Sjoerg
295612099Sjoerg	STRUCT_ASSIGN(curr_pos, cpos);
295712099Sjoerg}
295812099Sjoerg
295912099Sjoergstatic void
296091592Smarkmchkglvar(sym_t *sym)
296112099Sjoerg{
296291592Smarkm
296312099Sjoerg	if (sym->s_scl == TYPEDEF || sym->s_scl == ENUMCON)
296412099Sjoerg		return;
296591592Smarkm
296612099Sjoerg	if (sym->s_scl != EXTERN && sym->s_scl != STATIC)
296712099Sjoerg		lerror("chkglvar() 1");
296812099Sjoerg
296912099Sjoerg	glchksz(sym);
297012099Sjoerg
297112099Sjoerg	if (sym->s_scl == STATIC) {
297212099Sjoerg		if (sym->s_type->t_tspec == FUNC) {
297312099Sjoerg			if (sym->s_used && sym->s_def != DEF) {
297412099Sjoerg				STRUCT_ASSIGN(curr_pos, sym->s_upos);
297512099Sjoerg				/* static func. called but not def.. */
297612099Sjoerg				error(225, sym->s_name);
297712099Sjoerg			}
297812099Sjoerg		}
297912099Sjoerg		if (!sym->s_used) {
298012099Sjoerg			STRUCT_ASSIGN(curr_pos, sym->s_dpos);
298112099Sjoerg			if (sym->s_type->t_tspec == FUNC) {
298212099Sjoerg				if (sym->s_def == DEF) {
298312099Sjoerg					if (!sym->s_inline)
298412099Sjoerg						/* static function %s unused */
298512099Sjoerg						warning(236, sym->s_name);
298612099Sjoerg				} else {
298712099Sjoerg					/* static function %s decl. but ... */
298812099Sjoerg					warning(290, sym->s_name);
298912099Sjoerg				}
299012099Sjoerg			} else if (!sym->s_set) {
299112099Sjoerg				/* static variable %s unused */
299212099Sjoerg				warning(226, sym->s_name);
299312099Sjoerg			} else {
299412099Sjoerg				/* static variable %s set but not used */
299512099Sjoerg				warning(307, sym->s_name);
299612099Sjoerg			}
299712099Sjoerg		}
299812099Sjoerg		if (!tflag && sym->s_def == TDEF && sym->s_type->t_const) {
299912099Sjoerg			STRUCT_ASSIGN(curr_pos, sym->s_dpos);
300012099Sjoerg			/* const object %s should have initializer */
300112099Sjoerg			warning(227, sym->s_name);
300212099Sjoerg		}
300312099Sjoerg	}
300412099Sjoerg}
300512099Sjoerg
300612099Sjoergstatic void
300791592Smarkmglchksz(sym_t *sym)
300812099Sjoerg{
300991592Smarkm
301012099Sjoerg	if (sym->s_def == TDEF) {
301112099Sjoerg		if (sym->s_type->t_tspec == FUNC)
301212099Sjoerg			/*
3013108470Sschweikh			 * this can happen if a syntax error occurred
301412099Sjoerg			 * after a function declaration
301512099Sjoerg			 */
301612099Sjoerg			return;
301712099Sjoerg		STRUCT_ASSIGN(curr_pos, sym->s_dpos);
301812099Sjoerg		if (length(sym->s_type, sym->s_name) == 0 &&
301912099Sjoerg		    sym->s_type->t_tspec == ARRAY && sym->s_type->t_dim == 0) {
302012099Sjoerg			/* empty array declaration: %s */
302112099Sjoerg			if (tflag || (sym->s_scl == EXTERN && !sflag)) {
302212099Sjoerg				warning(190, sym->s_name);
302312099Sjoerg			} else {
302412099Sjoerg				error(190, sym->s_name);
302512099Sjoerg			}
302612099Sjoerg		}
302712099Sjoerg	}
302812099Sjoerg}
302912099Sjoerg
303012099Sjoerg/*
303112099Sjoerg * Prints information about location of previous definition/declaration.
303212099Sjoerg */
303312099Sjoergvoid
303491592Smarkmprevdecl(int msg, sym_t *psym)
303512099Sjoerg{
303612099Sjoerg	pos_t	cpos;
303712099Sjoerg
303812099Sjoerg	if (!rflag)
303912099Sjoerg		return;
304012099Sjoerg
304112099Sjoerg	STRUCT_ASSIGN(cpos, curr_pos);
304212099Sjoerg	STRUCT_ASSIGN(curr_pos, psym->s_dpos);
304312099Sjoerg	if (msg != -1) {
304412099Sjoerg		message(msg, psym->s_name);
304512099Sjoerg	} else if (psym->s_def == DEF || psym->s_def == TDEF) {
304612099Sjoerg		/* previous definition of %s */
304712099Sjoerg		message(261, psym->s_name);
304812099Sjoerg	} else {
304912099Sjoerg		/* previous declaration of %s */
305012099Sjoerg		message(260, psym->s_name);
305112099Sjoerg	}
305212099Sjoerg	STRUCT_ASSIGN(curr_pos, cpos);
305312099Sjoerg}
3054