Skip to content
Browse files

lint(1) implementation, by Jochen Pohl. named 'xlint' for a similar

reason to why 'install' is named 'xinstall'.
  • Loading branch information...
1 parent a2bca40 commit 80ff9e92597b4337a382e4cac87cfc5745865c22 cgd committed Jul 3, 1995
View
5 usr.bin/xlint/Makefile
@@ -0,0 +1,5 @@
+# $Id: Makefile,v 1.1.1.1 1995/07/03 20:56:35 cgd Exp $
+
+SUBDIR= lint1 lint2 xlint llib
+
+.include <bsd.subdir.mk>
View
16 usr.bin/xlint/lint1/Makefile
@@ -0,0 +1,16 @@
+# $Id: Makefile,v 1.1.1.1 1995/07/03 20:56:35 cgd Exp $
+
+PROG= lint1
+SRCS= cgram.c scan.c mem1.c mem.c err.c main1.c decl.c tree.c func.c \
+ init.c emit.c emit1.c
+NOMAN=
+LDADD+= -ll
+DPADD+= ${LIBL}
+YFLAGS= -d
+CFLAGS+=-I.
+LINTFLAGS=-aehpz
+CLEANFILES+=y.tab.h cgram.c scan.c
+
+BINDIR= /usr/libexec
+
+.include <bsd.prog.mk>
View
1,613 usr.bin/xlint/lint1/cgram.y
@@ -0,0 +1,1613 @@
+/*
+ * Copyright (c) 1994, 1995 Jochen Pohl
+ * All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Jochen Pohl for
+ * The NetBSD Project.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id: cgram.y,v 1.1.1.1 1995/07/03 20:56:35 cgd Exp $
+ */
+
+%{
+
+#ifndef lint
+static char rcsid[] = "$Id: cgram.y,v 1.1.1.1 1995/07/03 20:56:35 cgd Exp $";
+#endif
+
+#include <stdlib.h>
+#include <limits.h>
+
+#include "lint1.h"
+
+/*
+ * Contains the level of current declaration. 0 is extern.
+ * Used for symbol table entries.
+ */
+int blklev;
+
+/*
+ * level for memory allocation. Normaly the same as blklev.
+ * An exeption is the declaration of arguments in prototypes. Memory
+ * for these can't be freed after the declaration, but symbols must
+ * be removed from the symbol table after the declaration.
+ */
+int mblklev;
+
+static int toicon __P((tnode_t *));
+static void idecl __P((sym_t *, int));
+
+%}
+
+%union {
+ int y_int;
+ val_t *y_val;
+ sbuf_t *y_sb;
+ sym_t *y_sym;
+ op_t y_op;
+ scl_t y_scl;
+ tspec_t y_tspec;
+ tqual_t y_tqual;
+ type_t *y_type;
+ tnode_t *y_tnode;
+ strg_t *y_strg;
+ pqinf_t *y_pqinf;
+};
+
+%token T_LBRACE T_RBRACE T_LBRACK T_RBRACK T_LPARN T_RPARN
+%token <y_op> T_STROP
+%token <y_op> T_UNOP
+%token <y_op> T_INCDEC
+%token T_SIZEOF
+%token <y_op> T_MULT
+%token <y_op> T_DIVOP
+%token <y_op> T_ADDOP
+%token <y_op> T_SHFTOP
+%token <y_op> T_RELOP
+%token <y_op> T_EQOP
+%token <y_op> T_AND
+%token <y_op> T_XOR
+%token <y_op> T_OR
+%token <y_op> T_LOGAND
+%token <y_op> T_LOGOR
+%token T_QUEST
+%token T_COLON
+%token <y_op> T_ASSIGN
+%token <y_op> T_OPASS
+%token T_COMMA
+%token T_SEMI
+%token T_ELLIPSE
+
+/* storage classes (extern, static, auto, register and typedef) */
+%token <y_scl> T_SCLASS
+
+/* types (char, int, short, long, unsigned, signed, float, double, void) */
+%token <y_tspec> T_TYPE
+
+/* qualifiers (const, volatile) */
+%token <y_tqual> T_QUAL
+
+/* struct or union */
+%token <y_tspec> T_SOU
+
+/* enum */
+%token T_ENUM
+
+/* remaining keywords */
+%token T_CASE
+%token T_DEFAULT
+%token T_IF
+%token T_ELSE
+%token T_SWITCH
+%token T_DO
+%token T_WHILE
+%token T_FOR
+%token T_GOTO
+%token T_CONTINUE
+%token T_BREAK
+%token T_RETURN
+
+%left T_COMMA
+%right T_ASSIGN T_OPASS
+%right T_QUEST T_COLON
+%left T_LOGOR
+%left T_LOGAND
+%left T_OR
+%left T_XOR
+%left T_AND
+%left T_EQOP
+%left T_RELOP
+%left T_SHFTOP
+%left T_ADDOP
+%left T_MULT T_DIVOP
+%right T_UNOP T_INCDEC T_SIZEOF
+%left T_LPARN T_LBRACK T_STROP
+
+%token <y_sb> T_NAME
+%token <y_sb> T_TYPENAME
+%token <y_val> T_CON
+%token <y_strg> T_STRING
+
+%type <y_sym> func_decl
+%type <y_sym> notype_decl
+%type <y_sym> type_decl
+%type <y_type> typespec
+%type <y_type> clrtyp_typespec
+%type <y_type> notype_typespec
+%type <y_type> struct_spec
+%type <y_type> enum_spec
+%type <y_sym> struct_tag
+%type <y_sym> enum_tag
+%type <y_tspec> struct
+%type <y_sym> struct_declaration
+%type <y_sb> identifier
+%type <y_sym> member_declaration_list_with_rbrace
+%type <y_sym> member_declaration_list
+%type <y_sym> member_declaration
+%type <y_sym> notype_member_decls
+%type <y_sym> type_member_decls
+%type <y_sym> notype_member_decl
+%type <y_sym> type_member_decl
+%type <y_tnode> constant
+%type <y_sym> enum_declaration
+%type <y_sym> enums_with_opt_comma
+%type <y_sym> enums
+%type <y_sym> enumerator
+%type <y_sym> ename
+%type <y_sym> notype_direct_decl
+%type <y_sym> type_direct_decl
+%type <y_pqinf> pointer
+%type <y_pqinf> asterisk
+%type <y_sym> param_decl
+%type <y_sym> param_list
+%type <y_sym> abs_decl_param_list
+%type <y_sym> direct_param_decl
+%type <y_sym> notype_param_decl
+%type <y_sym> direct_notype_param_decl
+%type <y_pqinf> type_qualifier_list
+%type <y_pqinf> type_qualifier
+%type <y_sym> identifier_list
+%type <y_sym> abs_decl
+%type <y_sym> direct_abs_decl
+%type <y_sym> vararg_parameter_type_list
+%type <y_sym> parameter_type_list
+%type <y_sym> parameter_declaration
+%type <y_tnode> expr
+%type <y_tnode> term
+%type <y_tnode> func_arg_list
+%type <y_op> point_or_arrow
+%type <y_type> type_name
+%type <y_sym> abstract_declaration
+%type <y_tnode> do_while_expr
+%type <y_tnode> opt_expr
+%type <y_strg> string
+%type <y_strg> string2
+
+
+%%
+
+program:
+ /* empty */ {
+ if (sflag) {
+ /* empty translation unit */
+ error(272);
+ } else if (!tflag) {
+ /* empty translation unit */
+ warning(272);
+ }
+ }
+ | translation_unit
+ ;
+
+translation_unit:
+ ext_decl
+ | translation_unit ext_decl
+ ;
+
+ext_decl:
+ func_def {
+ glclrlc(0);
+ }
+ | data_def {
+ glclrlc(0);
+ }
+ ;
+
+data_def:
+ T_SEMI {
+ if (sflag) {
+ /* syntax error: empty declaration */
+ error(0);
+ } else if (!tflag) {
+ /* syntax error: empty declaration */
+ warning(0);
+ }
+ }
+ | clrtyp deftyp notype_init_decls T_SEMI {
+ if (sflag) {
+ /* old style declaration; add "int" */
+ error(1);
+ } else if (!tflag) {
+ /* old style declaration; add "int" */
+ warning(1);
+ }
+ }
+ | declmods deftyp T_SEMI {
+ if (dcs->scl == TYPEDEF) {
+ /* typedef declares no type name */
+ warning(72);
+ } else {
+ /* empty declaration */
+ warning(2);
+ }
+ }
+ | declmods deftyp notype_init_decls T_SEMI
+ | declspecs deftyp T_SEMI {
+ if (dcs->scl == TYPEDEF) {
+ /* typedef declares no type name */
+ warning(72);
+ } else if (!dcs->nedecl) {
+ /* empty declaration */
+ warning(2);
+ }
+ }
+ | declspecs deftyp type_init_decls T_SEMI
+ | error T_SEMI {
+ globclup();
+ }
+ | error T_RBRACE {
+ globclup();
+ }
+ ;
+
+func_def:
+ func_decl {
+ if ($1->s_type->t_tspec != FUNC) {
+ /* syntax error */
+ error(249);
+ YYERROR;
+ }
+ if ($1->s_type->t_typedef) {
+ /* ()-less function definition */
+ error(64);
+ YYERROR;
+ }
+ funcdef($1);
+ blklev++;
+ pushdecl(ARG);
+ } opt_arg_declaration_list {
+ popdecl();
+ blklev--;
+ cluparg();
+ pushctrl(0);
+ } comp_stmnt {
+ funcend();
+ popctrl(0);
+ }
+ ;
+
+func_decl:
+ clrtyp deftyp notype_decl {
+ $$ = $3;
+ }
+ | declmods deftyp notype_decl {
+ $$ = $3;
+ }
+ | declspecs deftyp type_decl {
+ $$ = $3;
+ }
+ ;
+
+opt_arg_declaration_list:
+ /* empty */
+ | arg_declaration_list
+ ;
+
+arg_declaration_list:
+ arg_declaration
+ | arg_declaration_list arg_declaration
+ /* XXX or better "arg_declaration error" ? */
+ | error
+ ;
+
+/*
+ * "arg_declaration" is separated from "declaration" because it
+ * needs other error handling.
+ */
+
+arg_declaration:
+ declmods deftyp T_SEMI {
+ /* empty declaration */
+ warning(2);
+ }
+ | declmods deftyp notype_init_decls T_SEMI
+ | declspecs deftyp T_SEMI {
+ if (!dcs->nedecl) {
+ /* empty declaration */
+ warning(2);
+ } else {
+ tspec_t ts = dcs->type->t_tspec;
+ /* %s declared in argument declaration list */
+ warning(3, ts == STRUCT ? "struct" :
+ (ts == UNION ? "union" : "enum"));
+ }
+ }
+ | declspecs deftyp type_init_decls T_SEMI {
+ if (dcs->nedecl) {
+ tspec_t ts = dcs->type->t_tspec;
+ /* %s declared in argument declaration list */
+ warning(3, ts == STRUCT ? "struct" :
+ (ts == UNION ? "union" : "enum"));
+ }
+ }
+ | declmods error
+ | declspecs error
+ ;
+
+declaration:
+ declmods deftyp T_SEMI {
+ if (dcs->scl == TYPEDEF) {
+ /* typedef declares no type name */
+ warning(72);
+ } else {
+ /* empty declaration */
+ warning(2);
+ }
+ }
+ | declmods deftyp notype_init_decls T_SEMI
+ | declspecs deftyp T_SEMI {
+ if (dcs->scl == TYPEDEF) {
+ /* typedef declares no type name */
+ warning(72);
+ } else if (!dcs->nedecl) {
+ /* empty declaration */
+ warning(2);
+ }
+ }
+ | declspecs deftyp type_init_decls T_SEMI
+ | error T_SEMI
+ ;
+
+clrtyp:
+ {
+ clrtyp();
+ }
+ ;
+
+deftyp:
+ /* empty */ {
+ deftyp();
+ }
+ ;
+
+declspecs:
+ clrtyp_typespec {
+ addtype($1);
+ }
+ | declmods typespec {
+ addtype($2);
+ }
+ | declspecs declmod
+ | declspecs notype_typespec {
+ addtype($2);
+ }
+ ;
+
+declmods:
+ clrtyp T_QUAL {
+ addqual($2);
+ }
+ | clrtyp T_SCLASS {
+ addscl($2);
+ }
+ | declmods declmod
+ ;
+
+declmod:
+ T_QUAL {
+ addqual($1);
+ }
+ | T_SCLASS {
+ addscl($1);
+ }
+ ;
+
+clrtyp_typespec:
+ clrtyp notype_typespec {
+ $$ = $2;
+ }
+ | T_TYPENAME clrtyp {
+ $$ = getsym($1)->s_type;
+ }
+ ;
+
+typespec:
+ notype_typespec {
+ $$ = $1;
+ }
+ | T_TYPENAME {
+ $$ = getsym($1)->s_type;
+ }
+ ;
+
+notype_typespec:
+ T_TYPE {
+ $$ = gettyp($1);
+ }
+ | struct_spec {
+ popdecl();
+ $$ = $1;
+ }
+ | enum_spec {
+ popdecl();
+ $$ = $1;
+ }
+ ;
+
+struct_spec:
+ struct struct_tag {
+ /*
+ * STDC requires that "struct a;" always introduces
+ * a new tag if "a" is not declared at current level
+ *
+ * yychar is valid because otherwise the parse would
+ * not been able to deceide if he must shift or reduce
+ */
+ $$ = mktag($2, $1, 0, yychar == T_SEMI);
+ }
+ | struct struct_tag {
+ dcs->tagtyp = mktag($2, $1, 1, 0);
+ } struct_declaration {
+ $$ = compltag(dcs->tagtyp, $4);
+ }
+ | struct {
+ dcs->tagtyp = mktag(NULL, $1, 1, 0);
+ } struct_declaration {
+ $$ = compltag(dcs->tagtyp, $3);
+ }
+ | struct error {
+ symtyp = FVFT;
+ $$ = gettyp(INT);
+ }
+ ;
+
+struct:
+ T_SOU {
+ symtyp = FTAG;
+ pushdecl($1 == STRUCT ? MOS : MOU);
+ dcs->offset = 0;
+ dcs->stralign = CHAR_BIT;
+ $$ = $1;
+ }
+ ;
+
+struct_tag:
+ identifier {
+ $$ = getsym($1);
+ }
+ ;
+
+struct_declaration:
+ struct_decl_lbrace member_declaration_list_with_rbrace {
+ $$ = $2;
+ }
+ ;
+
+struct_decl_lbrace:
+ T_LBRACE {
+ symtyp = FVFT;
+ }
+ ;
+
+member_declaration_list_with_rbrace:
+ member_declaration_list T_SEMI T_RBRACE {
+ $$ = $1;
+ }
+ | member_declaration_list T_RBRACE {
+ if (sflag) {
+ /* syntax req. ";" after last struct/union member */
+ error(66);
+ } else {
+ /* syntax req. ";" after last struct/union member */
+ warning(66);
+ }
+ $$ = $1;
+ }
+ | T_RBRACE {
+ $$ = NULL;
+ }
+ ;
+
+member_declaration_list:
+ member_declaration {
+ $$ = $1;
+ }
+ | member_declaration_list T_SEMI member_declaration {
+ $$ = lnklst($1, $3);
+ }
+ ;
+
+member_declaration:
+ noclass_declmods deftyp {
+ /* too late, i know, but getsym() compensates it */
+ symtyp = FMOS;
+ } notype_member_decls {
+ symtyp = FVFT;
+ $$ = $4;
+ }
+ | noclass_declspecs deftyp {
+ symtyp = FMOS;
+ } type_member_decls {
+ symtyp = FVFT;
+ $$ = $4;
+ }
+ | noclass_declmods deftyp {
+ /* struct or union member must be named */
+ warning(49);
+ $$ = NULL;
+ }
+ | noclass_declspecs deftyp {
+ /* struct or union member must be named */
+ warning(49);
+ $$ = NULL;
+ }
+ | error {
+ symtyp = FVFT;
+ $$ = NULL;
+ }
+ ;
+
+noclass_declspecs:
+ clrtyp_typespec {
+ addtype($1);
+ }
+ | noclass_declmods typespec {
+ addtype($2);
+ }
+ | noclass_declspecs T_QUAL {
+ addqual($2);
+ }
+ | noclass_declspecs notype_typespec {
+ addtype($2);
+ }
+ ;
+
+noclass_declmods:
+ clrtyp T_QUAL {
+ addqual($2);
+ }
+ | noclass_declmods T_QUAL {
+ addqual($2);
+ }
+ ;
+
+notype_member_decls:
+ notype_member_decl {
+ $$ = decl1str($1);
+ }
+ | notype_member_decls {
+ symtyp = FMOS;
+ } T_COMMA type_member_decl {
+ $$ = lnklst($1, decl1str($4));
+ }
+ ;
+
+type_member_decls:
+ type_member_decl {
+ $$ = decl1str($1);
+ }
+ | type_member_decls {
+ symtyp = FMOS;
+ } T_COMMA type_member_decl {
+ $$ = lnklst($1, decl1str($4));
+ }
+ ;
+
+notype_member_decl:
+ notype_decl {
+ $$ = $1;
+ }
+ | notype_decl T_COLON constant {
+ $$ = bitfield($1, toicon($3));
+ }
+ | {
+ symtyp = FVFT;
+ } T_COLON constant {
+ $$ = bitfield(NULL, toicon($3));
+ }
+ ;
+
+type_member_decl:
+ type_decl {
+ $$ = $1;
+ }
+ | type_decl T_COLON constant {
+ $$ = bitfield($1, toicon($3));
+ }
+ | {
+ symtyp = FVFT;
+ } T_COLON constant {
+ $$ = bitfield(NULL, toicon($3));
+ }
+ ;
+
+enum_spec:
+ enum enum_tag {
+ $$ = mktag($2, ENUM, 0, 0);
+ }
+ | enum enum_tag {
+ dcs->tagtyp = mktag($2, ENUM, 1, 0);
+ } enum_declaration {
+ $$ = compltag(dcs->tagtyp, $4);
+ }
+ | enum {
+ dcs->tagtyp = mktag(NULL, ENUM, 1, 0);
+ } enum_declaration {
+ $$ = compltag(dcs->tagtyp, $3);
+ }
+ | enum error {
+ symtyp = FVFT;
+ $$ = gettyp(INT);
+ }
+ ;
+
+enum:
+ T_ENUM {
+ symtyp = FTAG;
+ pushdecl(ENUMCON);
+ }
+ ;
+
+enum_tag:
+ identifier {
+ $$ = getsym($1);
+ }
+ ;
+
+enum_declaration:
+ enum_decl_lbrace enums_with_opt_comma T_RBRACE {
+ $$ = $2;
+ }
+ ;
+
+enum_decl_lbrace:
+ T_LBRACE {
+ symtyp = FVFT;
+ enumval = 0;
+ }
+ ;
+
+enums_with_opt_comma:
+ enums {
+ $$ = $1;
+ }
+ | enums T_COMMA {
+ if (sflag) {
+ /* trailing "," prohibited in enum declaration */
+ error(54);
+ } else {
+ /* trailing "," prohibited in enum declaration */
+ warning(54);
+ }
+ $$ = $1;
+ }
+ ;
+
+enums:
+ enumerator {
+ $$ = $1;
+ }
+ | enums T_COMMA enumerator {
+ $$ = lnklst($1, $3);
+ }
+ | error {
+ $$ = NULL;
+ }
+ ;
+
+enumerator:
+ ename {
+ $$ = ename($1, enumval, 1);
+ }
+ | ename T_ASSIGN constant {
+ $$ = ename($1, toicon($3), 0);
+ }
+ ;
+
+ename:
+ identifier {
+ $$ = getsym($1);
+ }
+ ;
+
+
+notype_init_decls:
+ notype_init_decl
+ | notype_init_decls T_COMMA type_init_decl
+ ;
+
+type_init_decls:
+ type_init_decl
+ | type_init_decls T_COMMA type_init_decl
+ ;
+
+notype_init_decl:
+ notype_decl {
+ idecl($1, 0);
+ chksz($1);
+ }
+ | notype_decl {
+ idecl($1, 1);
+ } T_ASSIGN initializer {
+ chksz($1);
+ }
+ ;
+
+type_init_decl:
+ type_decl {
+ idecl($1, 0);
+ chksz($1);
+ }
+ | type_decl {
+ idecl($1, 1);
+ } T_ASSIGN initializer {
+ chksz($1);
+ }
+ ;
+
+notype_decl:
+ notype_direct_decl {
+ $$ = $1;
+ }
+ | pointer notype_direct_decl {
+ $$ = addptr($2, $1);
+ }
+ ;
+
+notype_direct_decl:
+ T_NAME {
+ $$ = dname(getsym($1));
+ }
+ | T_LPARN type_decl T_RPARN {
+ $$ = $2;
+ }
+ | notype_direct_decl T_LBRACK T_RBRACK {
+ $$ = addarray($1, 0, 0);
+ }
+ | notype_direct_decl T_LBRACK constant T_RBRACK {
+ $$ = addarray($1, 1, toicon($3));
+ }
+ | notype_direct_decl param_list {
+ $$ = addfunc($1, $2);
+ popdecl();
+ blklev--;
+ }
+ ;
+
+type_decl:
+ type_direct_decl {
+ $$ = $1;
+ }
+ | pointer type_direct_decl {
+ $$ = addptr($2, $1);
+ }
+ ;
+
+type_direct_decl:
+ identifier {
+ $$ = dname(getsym($1));
+ }
+ | T_LPARN type_decl T_RPARN {
+ $$ = $2;
+ }
+ | type_direct_decl T_LBRACK T_RBRACK {
+ $$ = addarray($1, 0, 0);
+ }
+ | type_direct_decl T_LBRACK constant T_RBRACK {
+ $$ = addarray($1, 1, toicon($3));
+ }
+ | type_direct_decl param_list {
+ $$ = addfunc($1, $2);
+ popdecl();
+ blklev--;
+ }
+ ;
+
+/*
+ * param_decl and notype_param_decl exist to avoid a conflict in
+ * argument lists. A typename enclosed in parens should always be
+ * treated as a typename, not an argument.
+ * "typedef int a; f(int (a));" is "typedef int a; f(int foo(a));"
+ * not "typedef int a; f(int a);"
+ */
+param_decl:
+ direct_param_decl {
+ $$ = $1;
+ }
+ | pointer direct_param_decl {
+ $$ = addptr($2, $1);
+ }
+ ;
+
+direct_param_decl:
+ identifier {
+ $$ = dname(getsym($1));
+ }
+ | T_LPARN notype_param_decl T_RPARN {
+ $$ = $2;
+ }
+ | direct_param_decl T_LBRACK T_RBRACK {
+ $$ = addarray($1, 0, 0);
+ }
+ | direct_param_decl T_LBRACK constant T_RBRACK {
+ $$ = addarray($1, 1, toicon($3));
+ }
+ | direct_param_decl param_list {
+ $$ = addfunc($1, $2);
+ popdecl();
+ blklev--;
+ }
+ ;
+
+notype_param_decl:
+ direct_notype_param_decl {
+ $$ = $1;
+ }
+ | pointer direct_notype_param_decl {
+ $$ = addptr($2, $1);
+ }
+ ;
+
+direct_notype_param_decl:
+ T_NAME {
+ $$ = dname(getsym($1));
+ }
+ | T_LPARN notype_param_decl T_RPARN {
+ $$ = $2;
+ }
+ | direct_notype_param_decl T_LBRACK T_RBRACK {
+ $$ = addarray($1, 0, 0);
+ }
+ | direct_notype_param_decl T_LBRACK constant T_RBRACK {
+ $$ = addarray($1, 1, toicon($3));
+ }
+ | direct_notype_param_decl param_list {
+ $$ = addfunc($1, $2);
+ popdecl();
+ blklev--;
+ }
+ ;
+
+pointer:
+ asterisk {
+ $$ = $1;
+ }
+ | asterisk type_qualifier_list {
+ $$ = mergepq($1, $2);
+ }
+ | asterisk pointer {
+ $$ = mergepq($1, $2);
+ }
+ | asterisk type_qualifier_list pointer {
+ $$ = mergepq(mergepq($1, $2), $3);
+ }
+ ;
+
+asterisk:
+ T_MULT {
+ $$ = xcalloc(1, sizeof (pqinf_t));
+ $$->p_pcnt = 1;
+ }
+ ;
+
+type_qualifier_list:
+ type_qualifier {
+ $$ = $1;
+ }
+ | type_qualifier_list type_qualifier {
+ $$ = mergepq($1, $2);
+ }
+ ;
+
+type_qualifier:
+ T_QUAL {
+ $$ = xcalloc(1, sizeof (pqinf_t));
+ if (tflag) {
+ /* const and volatile illegal in traditional C */
+ warning(269);
+ } else {
+ if ($1 == CONST) {
+ $$->p_const = 1;
+ } else {
+ $$->p_volatile = 1;
+ }
+ }
+ }
+ ;
+
+param_list:
+ id_list_lparn identifier_list T_RPARN {
+ $$ = $2;
+ }
+ | abs_decl_param_list {
+ $$ = $1;
+ }
+ ;
+
+id_list_lparn:
+ T_LPARN {
+ blklev++;
+ pushdecl(PARG);
+ }
+ ;
+
+identifier_list:
+ T_NAME {
+ $$ = iname(getsym($1));
+ }
+ | identifier_list T_COMMA T_NAME {
+ $$ = lnklst($1, iname(getsym($3)));
+ }
+ | identifier_list error {
+ $$ = $1;
+ }
+ ;
+
+abs_decl_param_list:
+ abs_decl_lparn T_RPARN {
+ $$ = NULL;
+ }
+ | abs_decl_lparn vararg_parameter_type_list T_RPARN {
+ dcs->proto = 1;
+ $$ = $2;
+ }
+ | abs_decl_lparn error T_RPARN {
+ $$ = NULL;
+ }
+ ;
+
+abs_decl_lparn:
+ T_LPARN {
+ blklev++;
+ pushdecl(PARG);
+ }
+ ;
+
+vararg_parameter_type_list:
+ parameter_type_list {
+ $$ = $1;
+ }
+ | parameter_type_list T_COMMA T_ELLIPSE {
+ dcs->vararg = 1;
+ $$ = $1;
+ }
+ | T_ELLIPSE {
+ if (sflag) {
+ /* ANSI C requires formal parameter before "..." */
+ error(84);
+ } else if (!tflag) {
+ /* ANSI C requires formal parameter before "..." */
+ warning(84);
+ }
+ dcs->vararg = 1;
+ $$ = NULL;
+ }
+ ;
+
+parameter_type_list:
+ parameter_declaration {
+ $$ = $1;
+ }
+ | parameter_type_list T_COMMA parameter_declaration {
+ $$ = lnklst($1, $3);
+ }
+ ;
+
+parameter_declaration:
+ declmods deftyp {
+ $$ = decl1arg(aname(), 0);
+ }
+ | declspecs deftyp {
+ $$ = decl1arg(aname(), 0);
+ }
+ | declmods deftyp notype_param_decl {
+ $$ = decl1arg($3, 0);
+ }
+ /*
+ * param_decl is needed because of following conflict:
+ * "typedef int a; f(int (a));" could be parsed as
+ * "function with argument a of type int", or
+ * "function with an abstract argument of type function".
+ * This grammar realizes the second case.
+ */
+ | declspecs deftyp param_decl {
+ $$ = decl1arg($3, 0);
+ }
+ | declmods deftyp abs_decl {
+ $$ = decl1arg($3, 0);
+ }
+ | declspecs deftyp abs_decl {
+ $$ = decl1arg($3, 0);
+ }
+ ;
+
+initializer:
+ init_expr
+ ;
+
+init_expr:
+ expr %prec T_COMMA {
+ mkinit($1);
+ }
+ | init_lbrace init_expr_list init_rbrace
+ | init_lbrace init_expr_list T_COMMA init_rbrace
+ | error
+ ;
+
+init_expr_list:
+ init_expr %prec T_COMMA
+ | init_expr_list T_COMMA init_expr
+ ;
+
+init_lbrace:
+ T_LBRACE {
+ initlbr();
+ }
+ ;
+
+init_rbrace:
+ T_RBRACE {
+ initrbr();
+ }
+ ;
+
+type_name:
+ {
+ pushdecl(ABSTRACT);
+ } abstract_declaration {
+ popdecl();
+ $$ = $2->s_type;
+ }
+ ;
+
+abstract_declaration:
+ noclass_declmods deftyp {
+ $$ = decl1abs(aname());
+ }
+ | noclass_declspecs deftyp {
+ $$ = decl1abs(aname());
+ }
+ | noclass_declmods deftyp abs_decl {
+ $$ = decl1abs($3);
+ }
+ | noclass_declspecs deftyp abs_decl {
+ $$ = decl1abs($3);
+ }
+ ;
+
+abs_decl:
+ pointer {
+ $$ = addptr(aname(), $1);
+ }
+ | direct_abs_decl {
+ $$ = $1;
+ }
+ | pointer direct_abs_decl {
+ $$ = addptr($2, $1);
+ }
+ ;
+
+direct_abs_decl:
+ T_LPARN abs_decl T_RPARN {
+ $$ = $2;
+ }
+ | T_LBRACK T_RBRACK {
+ $$ = addarray(aname(), 0, 0);
+ }
+ | T_LBRACK constant T_RBRACK {
+ $$ = addarray(aname(), 1, toicon($2));
+ }
+ | direct_abs_decl T_LBRACK T_RBRACK {
+ $$ = addarray($1, 0, 0);
+ }
+ | direct_abs_decl T_LBRACK constant T_RBRACK {
+ $$ = addarray($1, 1, toicon($3));
+ }
+ | abs_decl_param_list {
+ $$ = addfunc(aname(), $1);
+ popdecl();
+ blklev--;
+ }
+ | direct_abs_decl abs_decl_param_list {
+ $$ = addfunc($1, $2);
+ popdecl();
+ blklev--;
+ }
+ ;
+
+stmnt:
+ labeled_stmnt
+ | expr_stmnt
+ | comp_stmnt
+ | selection_stmnt
+ | iteration_stmnt
+ | jump_stmnt {
+ ftflg = 0;
+ }
+ ;
+
+labeled_stmnt:
+ label stmnt
+ ;
+
+label:
+ identifier T_COLON {
+ symtyp = FLAB;
+ label(T_NAME, getsym($1), NULL);
+ }
+ | T_CASE constant T_COLON {
+ label(T_CASE, NULL, $2);
+ ftflg = 1;
+ }
+ | T_DEFAULT T_COLON {
+ label(T_DEFAULT, NULL, NULL);
+ ftflg = 1;
+ }
+ ;
+
+comp_stmnt:
+ compstmnt_lbrace declaration_list opt_stmnt_list compstmnt_rbrace
+ | compstmnt_lbrace opt_stmnt_list compstmnt_rbrace
+ ;
+
+compstmnt_lbrace:
+ T_LBRACE {
+ blklev++;
+ mblklev++;
+ pushdecl(AUTO);
+ }
+ ;
+
+compstmnt_rbrace:
+ T_RBRACE {
+ popdecl();
+ freeblk();
+ mblklev--;
+ blklev--;
+ ftflg = 0;
+ }
+ ;
+
+opt_stmnt_list:
+ /* empty */
+ | stmnt_list
+ ;
+
+stmnt_list:
+ stmnt
+ | stmnt_list stmnt
+ | stmnt_list error T_SEMI
+ ;
+
+expr_stmnt:
+ expr T_SEMI {
+ expr($1, 0, 0);
+ ftflg = 0;
+ }
+ | T_SEMI {
+ ftflg = 0;
+ }
+ ;
+
+selection_stmnt:
+ if_without_else {
+ if2();
+ if3(0);
+ }
+ | if_without_else T_ELSE {
+ if2();
+ } stmnt {
+ if3(1);
+ }
+ | if_without_else T_ELSE error {
+ if3(0);
+ }
+ | switch_expr stmnt {
+ switch2();
+ }
+ | switch_expr error {
+ switch2();
+ }
+ ;
+
+if_without_else:
+ if_expr stmnt
+ | if_expr error
+ ;
+
+if_expr:
+ T_IF T_LPARN expr T_RPARN {
+ if1($3);
+ }
+ ;
+
+switch_expr:
+ T_SWITCH T_LPARN expr T_RPARN {
+ switch1($3);
+ }
+ ;
+
+iteration_stmnt:
+ while_expr stmnt {
+ while2();
+ }
+ | while_expr error {
+ while2();
+ }
+ | do stmnt do_while_expr {
+ do2($3);
+ ftflg = 0;
+ }
+ | do error {
+ do2(NULL);
+ }
+ | for_exprs stmnt {
+ for2();
+ }
+ | for_exprs error {
+ for2();
+ }
+ ;
+
+while_expr:
+ T_WHILE T_LPARN expr T_RPARN {
+ while1($3);
+ }
+ ;
+
+do:
+ T_DO {
+ do1();
+ }
+ ;
+
+do_while_expr:
+ T_WHILE T_LPARN expr T_RPARN T_SEMI {
+ $$ = $3;
+ }
+ ;
+
+for_exprs:
+ T_FOR T_LPARN opt_expr T_SEMI opt_expr T_SEMI opt_expr T_RPARN {
+ for1($3, $5, $7);
+ }
+ ;
+
+opt_expr:
+ /* empty */ {
+ $$ = NULL;
+ }
+ | expr {
+ $$ = $1;
+ }
+ ;
+
+jump_stmnt:
+ goto identifier T_SEMI {
+ dogoto(getsym($2));
+ }
+ | goto error T_SEMI {
+ symtyp = FVFT;
+ }
+ | T_CONTINUE T_SEMI {
+ docont();
+ }
+ | T_BREAK T_SEMI {
+ dobreak();
+ }
+ | T_RETURN T_SEMI {
+ doreturn(NULL);
+ }
+ | T_RETURN expr T_SEMI {
+ doreturn($2);
+ }
+ ;
+
+goto:
+ T_GOTO {
+ symtyp = FLAB;
+ }
+ ;
+
+declaration_list:
+ declaration
+ | declaration_list declaration
+ ;
+
+constant:
+ expr %prec T_COMMA {
+ $$ = $1;
+ }
+ ;
+
+expr:
+ expr T_MULT expr {
+ $$ = build(MULT, $1, $3);
+ }
+ | expr T_DIVOP expr {
+ $$ = build($2, $1, $3);
+ }
+ | expr T_ADDOP expr {
+ $$ = build($2, $1, $3);
+ }
+ | expr T_SHFTOP expr {
+ $$ = build($2, $1, $3);
+ }
+ | expr T_RELOP expr {
+ $$ = build($2, $1, $3);
+ }
+ | expr T_EQOP expr {
+ $$ = build($2, $1, $3);
+ }
+ | expr T_AND expr {
+ $$ = build(AND, $1, $3);
+ }
+ | expr T_XOR expr {
+ $$ = build(XOR, $1, $3);
+ }
+ | expr T_OR expr {
+ $$ = build(OR, $1, $3);
+ }
+ | expr T_LOGAND expr {
+ $$ = build(LOGAND, $1, $3);
+ }
+ | expr T_LOGOR expr {
+ $$ = build(LOGOR, $1, $3);
+ }
+ | expr T_QUEST expr T_COLON expr {
+ $$ = build(QUEST, $1, build(COLON, $3, $5));
+ }
+ | expr T_ASSIGN expr {
+ $$ = build(ASSIGN, $1, $3);
+ }
+ | expr T_OPASS expr {
+ $$ = build($2, $1, $3);
+ }
+ | expr T_COMMA expr {
+ $$ = build(COMMA, $1, $3);
+ }
+ | term {
+ $$ = $1;
+ }
+ ;
+
+term:
+ T_NAME {
+ /* XXX realy neccessary? */
+ if (yychar < 0)
+ yychar = yylex();
+ $$ = getnnode(getsym($1), yychar);
+ }
+ | string {
+ $$ = getsnode($1);
+ }
+ | T_CON {
+ $$ = getcnode(gettyp($1->v_tspec), $1);
+ }
+ | T_LPARN expr T_RPARN {
+ if ($2 != NULL)
+ $2->tn_parn = 1;
+ $$ = $2;
+ }
+ | term T_INCDEC {
+ $$ = build($2 == INC ? INCAFT : DECAFT, $1, NULL);
+ }
+ | T_INCDEC term {
+ $$ = build($1 == INC ? INCBEF : DECBEF, $2, NULL);
+ }
+ | T_MULT term {
+ $$ = build(STAR, $2, NULL);
+ }
+ | T_AND term {
+ $$ = build(AMPER, $2, NULL);
+ }
+ | T_UNOP term {
+ $$ = build($1, $2, NULL);
+ }
+ | T_ADDOP term {
+ if (tflag && $1 == PLUS) {
+ /* unary + is illegal in traditional C */
+ warning(100);
+ }
+ $$ = build($1 == PLUS ? UPLUS : UMINUS, $2, NULL);
+ }
+ | term T_LBRACK expr T_RBRACK {
+ $$ = build(STAR, build(PLUS, $1, $3), NULL);
+ }
+ | term T_LPARN T_RPARN {
+ $$ = funccall($1, NULL);
+ }
+ | term T_LPARN func_arg_list T_RPARN {
+ $$ = funccall($1, $3);
+ }
+ | term point_or_arrow T_NAME {
+ if ($1 != NULL) {
+ sym_t *msym;
+ /* XXX strmemb should be integrated in build() */
+ if ($2 == ARROW) {
+ /* must to this before strmemb is called */
+ $1 = cconv($1);
+ }
+ msym = strmemb($1, $2, getsym($3));
+ $$ = build($2, $1, getnnode(msym, 0));
+ } else {
+ $$ = NULL;
+ }
+ }
+ | T_SIZEOF term %prec T_SIZEOF {
+ if (($$ = $2 == NULL ? NULL : bldszof($2->tn_type)) != NULL)
+ chkmisc($2, 0, 0, 0, 0, 0, 1);
+ }
+ | T_SIZEOF T_LPARN type_name T_RPARN %prec T_SIZEOF {
+ $$ = bldszof($3);
+ }
+ | T_LPARN type_name T_RPARN term %prec T_UNOP {
+ $$ = cast($4, $2);
+ }
+ ;
+
+string:
+ T_STRING {
+ $$ = $1;
+ }
+ | T_STRING string2 {
+ $$ = catstrg($1, $2);
+ }
+ ;
+
+string2:
+ T_STRING {
+ if (tflag) {
+ /* concatenated strings are illegal in traditional C */
+ warning(219);
+ }
+ $$ = $1;
+ }
+ | string2 T_STRING {
+ $$ = catstrg($1, $2);
+ }
+ ;
+
+func_arg_list:
+ expr %prec T_COMMA {
+ $$ = funcarg(NULL, $1);
+ }
+ | func_arg_list T_COMMA expr {
+ $$ = funcarg($1, $3);
+ }
+ ;
+
+point_or_arrow:
+ T_STROP {
+ symtyp = FMOS;
+ $$ = $1;
+ }
+ ;
+
+identifier:
+ T_NAME {
+ $$ = $1;
+ }
+ | T_TYPENAME {
+ $$ = $1;
+ }
+ ;
+
+%%
+
+/* ARGSUSED */
+int
+yyerror(msg)
+ char *msg;
+{
+ error(249);
+ if (++sytxerr >= 5)
+ norecover();
+ return (0);
+}
+
+/*
+ * Gets a node for a constant and returns the value of this constant
+ * as integer.
+ * Is the node not constant or too large for int or of type float,
+ * a warning will be printed.
+ *
+ * toicon() should be used only inside declarations. If it is used in
+ * expressions, it frees the memory used for the expression.
+ */
+static int
+toicon(tn)
+ tnode_t *tn;
+{
+ int i;
+ tspec_t t;
+ val_t *v;
+
+ v = constant(tn);
+
+ /*
+ * Abstract declarations are used inside expression. To free
+ * the memory would be a fatal error.
+ */
+ if (dcs->ctx != ABSTRACT)
+ tfreeblk();
+
+ if ((t = v->v_tspec) == FLOAT || t == DOUBLE || t == LDOUBLE) {
+ i = (int)v->v_ldbl;
+ /* integral constant expression expected */
+ error(55);
+ } else {
+ i = (int)v->v_quad;
+ if (isutyp(t)) {
+ if ((u_quad_t)v->v_quad > INT_MAX) {
+ /* integral constant too large */
+ warning(56);
+ }
+ } else {
+ if (v->v_quad > INT_MAX || v->v_quad < INT_MIN) {
+ /* integral constant too large */
+ warning(56);
+ }
+ }
+ }
+ free(v);
+ return (i);
+}
+
+static void
+idecl(decl, initflg)
+ sym_t *decl;
+ int initflg;
+{
+ initerr = 0;
+ initsym = decl;
+
+ switch (dcs->ctx) {
+ case EXTERN:
+ decl1ext(decl, initflg);
+ break;
+ case ARG:
+ (void)decl1arg(decl, initflg);
+ break;
+ case AUTO:
+ decl1loc(decl, initflg);
+ break;
+ default:
+ lerror("idecl()");
+ }
+
+ if (initflg && !initerr)
+ prepinit();
+}
View
3,065 usr.bin/xlint/lint1/decl.c
3,065 additions, 0 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
View
241 usr.bin/xlint/lint1/emit.c
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 1994, 1995 Jochen Pohl
+ * All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Jochen Pohl for
+ * The NetBSD Project.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id: emit.c,v 1.1.1.1 1995/07/03 20:56:36 cgd Exp $
+ */
+
+#ifndef lint
+static char rcsid[] = "$Id: emit.c,v 1.1.1.1 1995/07/03 20:56:36 cgd Exp $";
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <err.h>
+
+#include "lint.h"
+
+/* name and handle of output file */
+static const char *loname;
+static FILE *lout;
+
+/* output buffer data */
+ob_t ob;
+
+static void outxbuf __P((void));
+
+
+/*
+ * initialize output
+ */
+void
+outopen(name)
+ const char *name;
+{
+ loname = name;
+
+ /* Ausgabedatei oeffnen */
+ if ((lout = fopen(name, "w")) == NULL)
+ err(1, "cannot open '%s'", name);
+
+ /* Ausgabepuffer anlegen */
+ ob.o_len = 1024;
+ ob.o_end = (ob.o_buf = ob.o_nxt = xmalloc(ob.o_len)) + ob.o_len;
+}
+
+/*
+ * flush output buffer and close file
+ */
+void
+outclose()
+{
+ outclr();
+ if (fclose(lout) == EOF)
+ err(1, "cannot close '%s'", loname);
+}
+
+/*
+ * resize output buffer
+ */
+static void
+outxbuf()
+{
+ ptrdiff_t coffs;
+
+ coffs = ob.o_nxt - ob.o_buf;
+ ob.o_len *= 2;
+ ob.o_end = (ob.o_buf = xrealloc(ob.o_buf, ob.o_len)) + ob.o_len;
+ ob.o_nxt = ob.o_buf + coffs;
+}
+
+/*
+ * reset output buffer
+ * if it is not empty, it is flushed
+ */
+void
+outclr()
+{
+ size_t sz;
+
+ if (ob.o_buf != ob.o_nxt) {
+ outchar('\n');
+ sz = ob.o_nxt - ob.o_buf;
+ if (sz > ob.o_len)
+ errx(1, "internal error: outclr() 1");
+ if (fwrite(ob.o_buf, sz, 1, lout) != 1)
+ err(1, "cannot write to %s", loname);
+ ob.o_nxt = ob.o_buf;
+ }
+}
+
+/*
+ * write a character to the output buffer
+ */
+void
+outchar(c)
+ int c;
+{
+ if (ob.o_nxt == ob.o_end)
+ outxbuf();
+ *ob.o_nxt++ = (char)c;
+}
+
+/*
+ * write a character to the output buffer, qouted if necessary
+ */
+void
+outqchar(c)
+ int c;
+{
+ if (isprint(c) && c != '\\' && c != '"' && c != '\'') {
+ outchar(c);
+ } else {
+ outchar('\\');
+ switch (c) {
+ case '\\':
+ outchar('\\');
+ break;
+ case '"':
+ outchar('"');
+ break;
+ case '\'':
+ outchar('\'');
+ break;
+ case '\b':
+ outchar('b');
+ break;
+ case '\t':
+ outchar('t');
+ break;
+ case '\n':
+ outchar('n');
+ break;
+ case '\f':
+ outchar('f');
+ break;
+ case '\r':
+ outchar('r');
+ break;
+#ifdef __STDC__
+ case '\v':
+#else
+ case '\013':
+#endif
+ outchar('v');
+ break;
+#ifdef __STDC__
+ case '\a':
+#else
+ case '\007':
+#endif
+ outchar('a');
+ break;
+ default:
+ outchar((((u_int)c >> 6) & 07) + '0');
+ outchar((((u_int)c >> 3) & 07) + '0');
+ outchar((c & 07) + '0');
+ break;
+ }
+ }
+}
+
+/*
+ * write a strint to the output buffer
+ * the string must not contain any characters which
+ * should be quoted
+ */
+void
+outstrg(s)
+ const char *s;
+{
+ while (*s != '\0') {
+ if (ob.o_nxt == ob.o_end)
+ outxbuf();
+ *ob.o_nxt++ = *s++;
+ }
+}
+
+/*
+ * write an integer value to toe output buffer
+ */
+void
+outint(i)
+ int i;
+{
+ if ((ob.o_end - ob.o_nxt) < 3 * sizeof (int))
+ outxbuf();
+ ob.o_nxt += sprintf(ob.o_nxt, "%d", i);
+}
+
+/*
+ * write the name of a symbol to the output buffer
+ * the name is preceeded by its length
+ */
+void
+outname(name)
+ const char *name;
+{
+ if (name == NULL)
+ errx(1, "internal error: outname() 1");
+ outint((int)strlen(name));
+ outstrg(name);
+}
+
+/*
+ * write the name of the .c source
+ */
+void
+outsrc(name)
+ const char *name;
+{
+ outclr();
+ outchar('S');
+ outstrg(name);
+}
View
587 usr.bin/xlint/lint1/emit1.c
@@ -0,0 +1,587 @@
+/*
+ * Copyright (c) 1994, 1995 Jochen Pohl
+ * All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Jochen Pohl for
+ * The NetBSD Project.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id: emit1.c,v 1.1.1.1 1995/07/03 20:56:36 cgd Exp $
+ */
+
+#ifndef lint
+static char rcsid[] = "$Id: emit1.c,v 1.1.1.1 1995/07/03 20:56:36 cgd Exp $";
+#endif
+
+#include <ctype.h>
+
+#include "lint1.h"
+
+static void outtt __P((sym_t *, sym_t *));
+static void outfstrg __P((strg_t *));
+
+/*
+ * Write type into the output buffer.
+ * The type is written as a sequence of substrings, each of which describes a
+ * node of type type_t
+ * a node is coded as follows:
+ * char C
+ * signed char s C
+ * unsigned char u C
+ * short S
+ * unsigned short u S
+ * int I
+ * unsigned int u I
+ * long L
+ * unsigned long u L
+ * long long Q
+ * unsigned long long u Q
+ * float s D
+ * double D
+ * long double l D
+ * void V
+ * * P
+ * [n] A n
+ * () F
+ * (void) F 0
+ * (n arguments) F n arg1 arg2 ... argn
+ * (n arguments, ...) F n arg1 arg2 ... argn-1 E
+ * (a, b, c, ...) f n arg1 arg2 ...
+ * enum tag e T tag_or_typename
+ * struct tag s T tag_or_typename
+ * union tag u T tag_or_typename
+ *
+ * tag_or_typename 0 no tag or type name
+ * 1 n tag Tag
+ * 2 n typename only type name
+ *
+ * spaces are only for better readability
+ * additionaly it is possible to prepend the characters 'c' (for const)
+ * and 'v' (for volatile)
+ */
+void
+outtype(tp)
+ type_t *tp;
+{
+ int t, s, na;
+ sym_t *arg;
+ tspec_t ts;
+
+ while (tp != NULL) {
+ if ((ts = tp->t_tspec) == INT && tp->t_isenum)
+ ts = ENUM;
+ switch (ts) {
+ case CHAR: t = 'C'; s = '\0'; break;
+ case SCHAR: t = 'C'; s = 's'; break;
+ case UCHAR: t = 'C'; s = 'u'; break;
+ case SHORT: t = 'S'; s = '\0'; break;
+ case USHORT: t = 'S'; s = 'u'; break;
+ case INT: t = 'I'; s = '\0'; break;
+ case UINT: t = 'I'; s = 'u'; break;
+ case LONG: t = 'L'; s = '\0'; break;
+ case ULONG: t = 'L'; s = 'u'; break;
+ case QUAD: t = 'Q'; s = '\0'; break;
+ case UQUAD: t = 'Q'; s = 'u'; break;
+ case FLOAT: t = 'D'; s = 's'; break;
+ case DOUBLE: t = 'D'; s = '\0'; break;
+ case LDOUBLE: t = 'D'; s = 'l'; break;
+ case VOID: t = 'V'; s = '\0'; break;
+ case PTR: t = 'P'; s = '\0'; break;
+ case ARRAY: t = 'A'; s = '\0'; break;
+ case FUNC: t = 'F'; s = '\0'; break;
+ case ENUM: t = 'T'; s = 'e'; break;
+ case STRUCT: t = 'T'; s = 's'; break;
+ case UNION: t = 'T'; s = 'u'; break;
+ default:
+ lerror("outtyp() 1");
+ }
+ if (tp->t_const)
+ outchar('c');
+ if (tp->t_volatile)
+ outchar('v');
+ if (s != '\0')
+ outchar(s);
+ outchar(t);
+ if (ts == ARRAY) {
+ outint(tp->t_dim);
+ } else if (ts == ENUM) {
+ outtt(tp->t_enum->etag, tp->t_enum->etdef);
+ } else if (ts == STRUCT || ts == UNION) {
+ outtt(tp->t_str->stag, tp->t_str->stdef);
+ } else if (ts == FUNC && tp->t_proto) {
+ na = 0;
+ for (arg = tp->t_args; arg != NULL; arg = arg->s_nxt)
+ na++;
+ if (tp->t_vararg)
+ na++;
+ outint(na);
+ for (arg = tp->t_args; arg != NULL; arg = arg->s_nxt)
+ outtype(arg->s_type);
+ if (tp->t_vararg)
+ outchar('E');
+ }
+ tp = tp->t_subt;
+ }
+}
+
+/*
+ * type to string
+ * used for debugging output
+ *
+ * it uses its own output buffer for conversion
+ */
+const char *
+ttos(tp)
+ type_t *tp;
+{
+ static ob_t tob;
+ ob_t tmp;
+
+ if (tob.o_buf == NULL) {
+ tob.o_len = 64;
+ tob.o_buf = tob.o_nxt = xmalloc(tob.o_len);
+ tob.o_end = tob.o_buf + tob.o_len;
+ }
+
+ tmp = ob;
+ ob = tob;
+ ob.o_nxt = ob.o_buf;
+ outtype(tp);
+ outchar('\0');
+ tob = ob;
+ ob = tmp;
+
+ return (tob.o_buf);
+}
+
+/*
+ * write the name of a tag or typename
+ *
+ * if the tag is named, the name of the
+ * tag is written, otherwise, if a typename exists which
+ * refers to this tag, this typename is written
+ */
+static void
+outtt(tag, tdef)
+ sym_t *tag, *tdef;
+{
+ if (tag->s_name != unnamed) {
+ outint(1);
+ outname(tag->s_name);
+ } else if (tdef != NULL) {
+ outint(2);
+ outname(tdef->s_name);
+ } else {
+ outint(0);
+ }
+}
+
+/*
+ * write information about an global with storage class extern
+ * declared/defined symbol
+ *
+ * informations about function definitions are written in outfdef(),
+ * not here
+ */
+void
+outsym(sym, sc)
+ sym_t *sym;
+ scl_t sc;
+{
+ /*
+ * Static function declarations must also be written to the output
+ * file. Compatibility of function declarations (for both static
+ * and extern functions) must be checked in lint2. Lint1 can't do
+ * this, especially not, if functions are declared at block level
+ * before their first declaration at level 0.
+ */
+ if (sc != EXTERN && !(sc == STATIC && sym->s_type->t_tspec == FUNC))
+ return;
+
+ /* reset buffer */
+ outclr();
+
+ /*
+ * line number of .c source, 'd' for declaration, Id of current
+ * source (.c or .h), and line in current source.
+ */
+ outint(csrc_pos.p_line);
+ outchar('d');
+ outint(getfnid(sym->s_dpos.p_file));
+ outchar('.');
+ outint(sym->s_dpos.p_line);
+
+ /* flags */
+
+ switch (sym->s_def) {
+ case DEF:
+ /* defined */
+ outchar('d');
+ break;
+ case TDEF:
+ /* tentative defined */
+ outchar('t');
+ break;
+ case DECL:
+ /* declared */
+ outchar('e');
+ break;
+ default:
+ lerror("outsym() 2");
+ }
+ if (llibflg && sym->s_def != DECL) {
+ /*
+ * mark it as used so we get no warnings from lint2 about
+ * unused symbols in libraries.
+ */
+ outchar('u');
+ }
+
+ if (sc == STATIC)
+ outchar('s');
+
+ /* name of the symbol */
+ outname(sym->s_name);
+
+ /* type of the symbol */
+ outtype(sym->s_type);
+}
+
+/*
+ * write information about function definition
+ *
+ * this is also done for static functions so we are able to check if
+ * they are called with proper argument types
+ */
+void
+outfdef(fsym, tp, posp, rval, osdef, args)
+ sym_t *fsym, *args;
+ type_t *tp;
+ pos_t *posp;
+ int rval, osdef;
+{
+ int narg;
+ sym_t *arg;
+
+ /* reset the buffer */
+ outclr();
+
+ /*
+ * line number of .c source, 'd' for declaration, Id of current
+ * source (.c or .h), and line in current source
+ *
+ * we are already at the end of the function. If we are in the
+ * .c source, posp->p_line is correct, otherwise csrc_pos.p_line
+ * (for functions defined in header files).
+ */
+ if (posp->p_file == csrc_pos.p_file) {
+ outint(posp->p_line);
+ } else {
+ outint(csrc_pos.p_line);
+ }
+ outchar('d');
+ outint(getfnid(posp->p_file));
+ outchar('.');
+ outint(posp->p_line);
+
+ /* flags */
+
+ /* both SCANFLIKE and PRINTFLIKE imply VARARGS */
+ if (prflstrg != -1) {
+ nvararg = prflstrg;
+ } else if (scflstrg != -1) {
+ nvararg = scflstrg;
+ }
+
+ if (nvararg != -1) {
+ outchar('v');
+ outint(nvararg);
+ }
+ if (scflstrg != -1) {
+ outchar('S');
+ outint(scflstrg);
+ }
+ if (prflstrg != -1) {
+ outchar('P');
+ outint(prflstrg);
+ }
+ nvararg = prflstrg = scflstrg = -1;
+
+ outchar('d');
+
+ if (rval)
+ /* has return value */
+ outchar('r');
+
+ if (llibflg)
+ /*
+ * mark it as used so lint2 does not complain about
+ * unused symbols in libraries
+ */
+ outchar('u');
+
+ if (osdef)
+ /* old style function definition */
+ outchar('o');
+
+ if (fsym->s_scl == STATIC)
+ outchar('s');
+
+ /* name of function */
+ outname(fsym->s_name);
+
+ /* argument types and return value */
+ if (osdef) {
+ narg = 0;
+ for (arg = args; arg != NULL; arg = arg->s_nxt)
+ narg++;
+ outchar('f');
+ outint(narg);
+ for (arg = args; arg != NULL; arg = arg->s_nxt)
+ outtype(arg->s_type);
+ outtype(tp->t_subt);
+ } else {
+ outtype(tp);
+ }
+}
+
+/*
+ * write out all information necessary for lint2 to check function
+ * calls
+ *
+ * rvused is set if the return value is used (asigned to a variable)
+ * rvdisc is set if the return value is not used and not ignored
+ * (casted to void)
+ */
+void
+outcall(tn, rvused, rvdisc)
+ tnode_t *tn;
+ int rvused, rvdisc;
+{
+ tnode_t *args, *arg;
+ int narg, n, i;
+ quad_t q;
+ tspec_t t;
+
+ /* reset buffer */
+ outclr();
+
+ /*
+ * line number of .c source, 'c' for function call, Id of current
+ * source (.c or .h), and line in current source
+ */
+ outint(csrc_pos.p_line);
+ outchar('c');
+ outint(getfnid(curr_pos.p_file));
+ outchar('.');
+ outint(curr_pos.p_line);
+
+ /*
+ * flags; 'u' and 'i' must be last to make sure a letter
+ * is between the numeric argument of a flag and the name of
+ * the function
+ */
+ narg = 0;
+ args = tn->tn_right;
+ for (arg = args; arg != NULL; arg = arg->tn_right)
+ narg++;
+ /* informations about arguments */
+ for (n = 1; n <= narg; n++) {
+ /* the last argument is the top one in the tree */
+ for (i = narg, arg = args; i > n; i--, arg = arg->tn_right) ;
+ arg = arg->tn_left;
+ if (arg->tn_op == CON) {
+ if (isityp(t = arg->tn_type->t_tspec)) {
+ /*
+ * XXX it would probably be better to
+ * explizitly test the sign
+ */
+ if ((q = arg->tn_val->v_quad) == 0) {
+ /* zero constant */
+ outchar('z');
+ } else if (msb(q, t, 0) == 0) {
+ /* positive if casted to signed */
+ outchar('p');
+ } else {
+ /* negative if casted to signed */
+ outchar('n');
+ }
+ outint(n);
+ }
+ } else if (arg->tn_op == AMPER &&
+ arg->tn_left->tn_op == STRING &&
+ arg->tn_left->tn_strg->st_tspec == CHAR) {
+ /* constant string, write all format specifiers */
+ outchar('s');
+ outint(n);
+ outfstrg(arg->tn_left->tn_strg);
+ }
+
+ }
+ /* return value discarded/used/ignored */
+ outchar(rvdisc ? 'd' : (rvused ? 'u' : 'i'));
+
+ /* name of the called function */
+ outname(tn->tn_left->tn_left->tn_sym->s_name);
+
+ /* types of arguments */
+ outchar('f');
+ outint(narg);
+ for (n = 1; n <= narg; n++) {
+ /* the last argument is the top one in the tree */
+ for (i = narg, arg = args; i > n; i--, arg = arg->tn_right) ;
+ outtype(arg->tn_left->tn_type);
+ }
+ /* expected type of return value */
+ outtype(tn->tn_type);
+}
+
+/*
+ * extracts potential format specifiers for printf() and scanf() and
+ * writes them, enclosed in "" and qouted if necessary, to the output buffer
+ */
+static void
+outfstrg(strg)
+ strg_t *strg;
+{
+ int c, oc, first;
+ u_char *cp;
+
+ if (strg->st_tspec != CHAR)
+ lerror("outfstrg() 1");
+
+ cp = strg->st_cp;
+
+ outchar('"');
+
+ c = *cp++;
+
+ while (c != '\0') {
+
+ if (c != '%') {
+ c = *cp++;
+ continue;
+ }
+
+ outqchar('%');
+ c = *cp++;
+
+ /* flags for printf and scanf and *-fieldwidth for printf */
+ while (c != '\0' && (c == '-' || c == '+' || c == ' ' ||
+ c == '#' || c == '0' || c == '*')) {
+ outqchar(c);
+ c = *cp++;
+ }
+
+ /* numeric field width */
+ while (c != '\0' && isdigit(c)) {
+ outqchar(c);
+ c = *cp++;
+ }
+
+ /* precision for printf */
+ if (c == '.') {
+ outqchar(c);
+ if ((c = *cp++) == '*') {
+ outqchar(c);
+ c = *cp++;
+ } else {
+ while (c != '\0' && isdigit(c)) {
+ outqchar(c);
+ c = *cp++;
+ }
+ }
+ }
+
+ /* h, l, L and q flags fpr printf and scanf */
+ if (c == 'h' || c == 'l' || c == 'L' || c == 'q') {
+ outqchar(c);
+ c = *cp++;
+ }
+
+ /*
+ * The last character. It is always written so we can detect
+ * invalid format specifiers.
+ */
+ if (c != '\0') {
+ outqchar(c);
+ oc = c;
+ c = *cp++;
+ /*
+ * handle [ for scanf. [-] means that a minus sign
+ * was found at an undefined position.
+ */
+ if (oc == '[') {
+ if (c == '^')
+ c = *cp++;
+ if (c == ']')
+ c = *cp++;
+ first = 1;
+ while (c != '\0' && c != ']') {
+ if (c == '-') {
+ if (!first && *cp != ']')
+ outqchar(c);
+ }
+ first = 0;
+ c = *cp++;
+ }
+ if (c == ']') {
+ outqchar(c);
+ c = *cp++;
+ }
+ }
+ }
+
+ }
+
+ outchar('"');
+}
+
+/*
+ * writes a record if sym was used
+ */
+void
+outusg(sym)
+ sym_t *sym;
+{
+ /* reset buffer */
+ outclr();
+
+ /*
+ * line number of .c source, 'u' for used, Id of current
+ * source (.c or .h), and line in current source
+ */
+ outint(csrc_pos.p_line);
+ outchar('u');
+ outint(getfnid(curr_pos.p_file));
+ outchar('.');
+ outint(curr_pos.p_line);
+
+ /* necessary to delimit both numbers */
+ outchar('x');
+
+ /* Den Namen des Symbols ausgeben */
+ outname(sym->s_name);
+}
View
503 usr.bin/xlint/lint1/err.c
@@ -0,0 +1,503 @@
+/*
+ * Copyright (c) 1994, 1995 Jochen Pohl
+ * All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Jochen Pohl for
+ * The NetBSD Project.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id: err.c,v 1.1.1.1 1995/07/03 20:56:36 cgd Exp $
+ */
+
+#ifndef lint
+static char rcsid[] = "$Id: err.c,v 1.1.1.1 1995/07/03 20:56:36 cgd Exp $";
+#endif
+
+/* number of errors found */
+int nerr;
+
+/* number of syntax errors */
+int sytxerr;
+
+#include <stdlib.h>
+#ifdef __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+#include "lint1.h"
+
+static const char *basename __P((const char *));
+
+const char *msgs[] = {
+ "syntax error: empty declaration", /* 0 */
+ "old style declaration; add int", /* 1 */
+ "empty declaration", /* 2 */
+ "%s declared in argument declaration list", /* 3 */
+ "illegal type combination", /* 4 */
+ "modifying typedef with '%s'; only qualifiers allowed", /* 5 */
+ "use 'double' instead of 'long float'", /* 6 */
+ "only one storage class allowed", /* 7 */
+ "illegal storage class", /* 8 */
+ "only register valid as formal parameter storage class", /* 9 */
+ "duplicate '%s'", /* 10 */
+ "bit-field initializer out of range", /* 11 */
+ "compiler takes size of function", /* 12 */
+ "incomplete enum type: %s", /* 13 */
+ "compiler takes alignment of function", /* 14 */
+ "function returns illegal type", /* 15 */
+ "array of function is illegal", /* 16 */
+ "null dimension", /* 17 */
+ "illegal use of 'void'", /* 18 */
+ "void type for %s", /* 19 */
+ "zero or negative array dimension", /* 20 */
+ "redeclaration of formal parameter %s", /* 21 */
+ "incomplete or misplaced function definition", /* 22 */
+ "undefined label %s", /* 23 */
+ "cannot initialize function: %s", /* 24 */
+ "cannot initialize typedef: %s", /* 25 */
+ "cannot initialize extern declaration: %s", /* 26 */
+ "redeclaration of %s", /* 27 */
+ "redefinition of %s", /* 28 */
+ "previously declared extern, becomes static: %s", /* 29 */
+ "redeclaration of %s; ANSI C requires static", /* 30 */
+ "incomplete structure or union %s: %s", /* 31 */
+ "argument type defaults to 'int': %s", /* 32 */
+ "duplicate member name: %s", /* 33 */
+ "nonportable bit-field type", /* 34 */
+ "illegal bit-field type", /* 35 */
+ "illegal bit-field size", /* 36 */
+ "zero size bit-field", /* 37 */
+ "function illegal in structure or union", /* 38 */
+ "illegal zero sized structure member: %s", /* 39 */
+ "unknown size: %s", /* 40 */
+ "illegal use of bit-field", /* 41 */
+ "forward reference to enum type", /* 42 */
+ "redefinition hides earlier one: %s", /* 43 */
+ "declaration introduces new type in ANSI C: %s %s", /* 44 */
+ "base type is really '%s %s'", /* 45 */
+ "(%s) tag redeclared", /* 46 */
+ "zero sized %s", /* 47 */
+ "overflow in enumeration values: %s", /* 48 */
+ "struct or union member must be named", /* 49 */
+ "a function is declared as an argument: %s", /* 50 */
+ "parameter mismatch: %d declared, %d defined", /* 51 */
+ "cannot initialize parameter: %s", /* 52 */
+ "declared argument %s is missing", /* 53 */
+ "trailing ',' prohibited in enum declaration", /* 54 */
+ "integral constant expression expected", /* 55 */
+ "integral constant too large", /* 56 */
+ "enumeration constant hides parameter: %s", /* 57 */
+ "type does not match prototype: %s", /* 58 */
+ "formal parameter lacks name: param #%d", /* 59 */
+ "void must be sole parameter", /* 60 */
+ "void parameter cannot have name: %s", /* 61 */
+ "function prototype parameters must have types", /* 62 */
+ "prototype does not match old-style definition", /* 63 */
+ "()-less function definition", /* 64 */
+ "%s has no named members", /* 65 */
+ "syntax requires ';' after last struct/union member", /* 66 */
+ "cannot return incomplete type", /* 67 */
+ "typedef already qualified with '%s'", /* 68 */
+ "inappropriate qualifiers with 'void'", /* 69 */
+ "%soperand of '%s' is unsigned in ANSI C", /* 70 */
+ "too many characters in character constant", /* 71 */
+ "typedef declares no type name", /* 72 */
+ "empty character constant", /* 73 */
+ "no hex digits follow \\x", /* 74 */
+ "overflow in hex escape", /* 75 */
+ "character escape does not fit in character", /* 76 */
+ "bad octal digit %c", /* 77 */
+ "nonportable character escape", /* 78 */
+ "dubious escape \\%c", /* 79 */
+ "dubious escape \\%o", /* 80 */
+ "\\a undefined in traditional C", /* 81 */
+ "\\x undefined in traditional C", /* 82 */
+ "storage class after type is obsolescent", /* 83 */
+ "ANSI C requires formal parameter before '...'", /* 84 */
+ "dubious tag declaration: %s %s", /* 85 */
+ "automatic hides external declaration: %s", /* 86 */
+ "static hides external declaration: %s", /* 87 */
+ "typedef hides external declaration: %s", /* 88 */
+ "typedef redeclared: %s", /* 89 */
+ "inconsistent redeclaration of extern: %s", /* 90 */
+ "declaration hides parameter: %s", /* 91 */
+ "inconsistent redeclaration of static: %s", /* 92 */
+ "dubious static function at block level: %s", /* 93 */
+ "function has illegal storage class: %s", /* 94 */
+ "declaration hides earlier one: %s", /* 95 */
+ "cannot dereference non-pointer type", /* 96 */
+ "suffix U is illegal in traditional C", /* 97 */
+ "suffixes F and L are illegal in traditional C", /* 98 */
+ "%s undefined", /* 99 */
+ "unary + is illegal in traditional C", /* 100 */
+ "undefined struct/union member: %s", /* 101 */
+ "illegal member use: %s", /* 102 */
+ "left operand of '.' must be struct/union object", /* 103 */
+ "left operand of '->' must be pointer to struct/union", /* 104 */
+ "non-unique member requires struct/union %s", /* 105 */
+ "left operand of '->' must be pointer", /* 106 */
+ "operands of '%s' have incompatible types", /* 107 */
+ "operand of '%s' has incompatible type", /* 108 */
+ "void type illegal in expression", /* 109 */
+ "pointer to function is not allowed here", /* 110 */
+ "unacceptable operand of '%s'", /* 111 */
+ "cannot take address of bit-field", /* 112 */
+ "cannot take address of register %s", /* 113 */
+ "%soperand of '%s' must be lvalue", /* 114 */
+ "%soperand of '%s' must be modifiable lvalue", /* 115 */
+ "illegal pointer subtraction", /* 116 */
+ "bitwise operation on signed value possibly nonportable", /* 117 */
+ "semantics of '%s' change in ANSI C; use explicit cast", /* 118 */
+ "conversion of '%s' to '%s' is out of range", /* 119 */
+ "bitwise operation on signed value nonportable", /* 120 */
+ "negative shift", /* 121 */
+ "shift greater than size of object", /* 122 */
+ "illegal combination of pointer and integer, op %s", /* 123 */
+ "illegal pointer combination, op %s", /* 124 */
+ "ANSI C forbids ordered comparisons of pointers to functions",/* 125 */
+ "incompatible types in conditional", /* 126 */
+ "'&' before array or function: ignored", /* 127 */
+ "operands have incompatible pointer types, op %s", /* 128 */
+ "expression has null effect", /* 129 */
+ "enum type mismatch, op %s", /* 130 */
+ "conversion to '%s' may sign-extend incorrectly", /* 131 */