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