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