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