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