introduction of lint source code, governed by ifdef LINT

This commit is contained in:
dick 1988-09-20 16:44:27 +00:00
parent 7e502b0937
commit 6839d8afb1
35 changed files with 3200 additions and 17 deletions

View file

@ -5,6 +5,7 @@
/* $Header$ */
/* L E X I C A L A N A L Y Z E R */
#include "lint.h"
#include <alloc.h>
#include "nofloat.h"
#include "idfsize.h"
@ -72,6 +73,9 @@ LLlex()
ASIDE = 0;
}
else { /* read ahead and return the old one */
#ifdef LINT
move_NOT2s();
#endif LINT
dot = ahead;
/* the following test is performed due to the dual
task of LLlex(): it is also called for parsing the
@ -472,6 +476,10 @@ skipcomment()
NoUnstack++;
LoadChar(c);
#ifdef LINT
lint_comment(-2);
lint_comment(c);
#endif LINT
do {
while (c != '*') {
if (class(c) == STNL)
@ -482,8 +490,14 @@ skipcomment()
return;
}
LoadChar(c);
#ifdef LINT
lint_comment(c);
#endif LINT
} /* last Character seen was '*' */
LoadChar(c);
#ifdef LINT
lint_comment(c);
#endif LINT
} while (c != '/');
NoUnstack--;
}

139
lang/cem/cemcom/LintPars Normal file
View file

@ -0,0 +1,139 @@
!File: lint.h
#define LINT 1 /* if defined, 'lint' is produced */
!File: pathlength.h
#define PATHLENGTH 1024 /* max. length of path to file */
!File: errout.h
#define ERROUT STDERR /* file pointer for writing messages */
#define MAXERR_LINE 5 /* maximum number of error messages given
on the same input line. */
!File: idfsize.h
#define IDFSIZE 64 /* maximum significant length of an identifier */
!File: numsize.h
#define NUMSIZE 256 /* maximum length of a numeric constant */
!File: nparams.h
#define NPARAMS 32 /* maximum number of parameters of macros */
!File: ifdepth.h
#define IFDEPTH 256 /* maximum number of nested if-constructions */
!File: density.h
#define DENSITY 2 /* see switch.[ch] for an explanation */
!File: lapbuf.h
#define LAPBUF 4096 /* size of macro actual parameter buffer */
!File: strsize.h
#define ISTRSIZE 32 /* minimum number of bytes allocated for
storing a string */
#define RSTRSIZE 8 /* step size in enlarging the memory for
the storage of a string */
!File: target_sizes.h
#define MAXSIZE 8 /* the maximum of the SZ_* constants */
/* target machine sizes */
#define SZ_CHAR (arith)1
#define SZ_SHORT (arith)2
#define SZ_WORD (arith)4
#define SZ_INT (arith)4
#define SZ_LONG (arith)4
#ifndef NOFLOAT
#define SZ_FLOAT (arith)4
#define SZ_DOUBLE (arith)8
#endif NOFLOAT
#define SZ_POINTER (arith)4
/* target machine alignment requirements */
#define AL_CHAR 1
#define AL_SHORT SZ_SHORT
#define AL_WORD SZ_WORD
#define AL_INT SZ_WORD
#define AL_LONG SZ_WORD
#ifndef NOFLOAT
#define AL_FLOAT SZ_WORD
#define AL_DOUBLE SZ_WORD
#endif NOFLOAT
#define AL_POINTER SZ_WORD
#define AL_STRUCT 1
#define AL_UNION 1
!File: botch_free.h
#undef BOTCH_FREE 1 /* when defined, botch freed memory, as a check */
!File: dataflow.h
#undef DATAFLOW 1 /* produce some compile-time xref */
!File: debug.h
#undef DEBUG 1 /* perform various self-tests */
!File: use_tmp.h
#undef USE_TMP 1 /* collect exa, exp, ina and inp commands
and let them precede the rest of
the generated compact code */
!File: parbufsize.h
#define PARBUFSIZE 1024
!File: textsize.h
#define ITEXTSIZE 8 /* 1st piece of memory for repl. text */
#define RTEXTSIZE 8 /* stepsize for enlarging repl.text */
!File: inputtype.h
#define INP_READ_IN_ONE 1 /* read input file in one */
!File: nopp.h
#undef NOPP 1 /* if NOT defined, use built-int preprocessor */
!File: nobitfield.h
#undef NOBITFIELD 1 /* if NOT defined, implement bitfields */
!File: spec_arith.h
/* describes internal compiler arithmetics */
#undef SPECIAL_ARITHMETICS /* something different from native long */
!File: static.h
#define GSTATIC /* for large global "static" arrays */
!File: nofloat.h
#undef NOFLOAT 1 /* if NOT defined, floats are implemented */
!File: noRoption.h
#undef NOROPTION 1 /* if NOT defined, R option is implemented */
!File: nocross.h
#undef NOCROSS 1 /* if NOT defined, cross compiler */
!File: regcount.h
#undef REGCOUNT 1 /* count occurrences for register messages */

View file

@ -28,6 +28,8 @@ OLIBS = $(INPLIB) $(EMMESOLIB) $(EMOLIB) $(EMKLIB) $(PRTLIB) $(STRLIB) \
$(ALLOCLIB) $(MALLOC) $(SYSLIB)
CELIBS = $(INPLIB) $(EMMESCELIB) $(EMCELIB) $(PRTLIB) $(STRLIB) \
$(ALLOCLIB) $(MALLOC) $(SYSLIB)
LLIBS = $(INPLIB) $(EMMESLIB) $(PRTLIB) $(STRLIB) \
$(ALLOCLIB) $(MALLOC) $(SYSLIB)
LIB_INCLUDES = -I$(EMHOME)/modules/h -I$(EMHOME)/modules/pkg
EM_INCLUDES = -I$(EMHOME)/h
SYSLLIB = $(EMHOME)/modules/lib/llib-lsystem.ln
@ -66,7 +68,8 @@ CSRC = main.c idf.c declarator.c decspecs.c struct.c \
input.c domacro.c replace.c init.c options.c \
scan.c skip.c stack.c type.c ch7mon.c label.c eval.c \
switch.c conversion.c util.c \
blocks.c dataflow.c Version.c
blocks.c dataflow.c Version.c \
l_lint.c l_states.c l_misc.c l_ev_ord.c l_outdef.c l_comment.c l_dummy.c
COBJ = main.o idf.o declarator.o decspecs.o struct.o \
expr.o ch7.o ch7bin.o cstoper.o arith.o \
asm.o code.o dumpidf.o error.o field.o\
@ -74,7 +77,8 @@ COBJ = main.o idf.o declarator.o decspecs.o struct.o \
input.o domacro.o replace.o init.o options.o \
scan.o skip.o stack.o type.o ch7mon.o label.o eval.o \
switch.o conversion.o util.o \
blocks.o dataflow.o Version.o
blocks.o dataflow.o Version.o \
l_lint.o l_states.o l_misc.o l_ev_ord.o l_outdef.o l_comment.o l_dummy.o
# Objects of other generated C files
GCSRC = char.c symbol2str.c next.c
@ -82,16 +86,18 @@ GOBJ = char.o symbol2str.o next.o
STRSRC = code.str declar.str decspecs.str def.str expr.str field.str \
estack.str util.str \
idf.str macro.str stack.str stmt.str struct.str switch.str type.str
idf.str macro.str stack.str stmt.str struct.str switch.str type.str \
l_brace.str l_state.str l_outdef.str
# generated source files
GHSTRSRC = code.h declar.h decspecs.h def.h expr.h field.h \
estack.h util.h \
idf.h macro.h stack.h stmt.h struct.h switch.h type.h
idf.h macro.h stack.h stmt.h struct.h switch.h type.h \
l_brace.h l_state.h l_outdef.h
GSRC = $(GCSRC) $(GHSTRSRC)
# .h files generated by `make hfiles LLfiles'; PLEASE KEEP THIS UP-TO-DATE!
GHSRC = botch_free.h dataflow.h debug.h density.h errout.h \
idfsize.h ifdepth.h inputtype.h lapbuf.h \
idfsize.h ifdepth.h inputtype.h lapbuf.h lint.h \
nobitfield.h nofloat.h nopp.h noRoption.h nocross.h \
nparams.h numsize.h parbufsize.h pathlength.h Lpars.h \
strsize.h target_sizes.h textsize.h use_tmp.h spec_arith.h static.h \
@ -99,7 +105,7 @@ GHSRC = botch_free.h dataflow.h debug.h density.h errout.h \
HSRC = LLlex.h align.h arith.h assert.h atw.h class.h \
input.h interface.h label.h level.h mes.h sizes.h specials.h \
file_info.h tokenname.h
file_info.h tokenname.h l_lint.h
HFILES = $(HSRC) $(GHSRC) $(GHSTRSRC)
@ -111,6 +117,12 @@ GENERATED = tab tokenfile.g Lpars.h LLfiles LL.output lint.out \
OBJ = $(COBJ) $(LOBJ) $(GOBJ)
SRC = $(CSRC) $(LCSRC) $(GCSRC)
LINT = /usr/bin/lint
LINTFLAGS =
MYLINT = ../lint
MYLINTFLAGS = #-xh
#EXCLEXCLEXCLEXCL
.SUFFIXES: .str .h
@ -135,6 +147,11 @@ CEmain: Cfiles
sh -c 'if $(CC) nmclash.c > /dev/null 2>&1 ; then make "EMHOME="$(EMHOME) "COPTIONS="-DCODE_EXPANDER $(CURRDIR)/cemain ; else EMHOME=$(EMHOME); export EMHOME; ./Resolve cemain ; fi'
@rm -f nmclash.o a.out *.o
Lnt: Cfiles
sh -c 'if $(CC) nmclash.c > /dev/null 2>&1 ; then make "EMHOME="$(EMHOME) $(CURRDIR)/lnt ; else EMHOME=$(EMHOME); export EMHOME; ./Resolve lnt ; fi'
make "EMHOME="$(EMHOME) $(CURRDIR)/lnt
@rm -f nmclash.o a.out
install: Main
rm -f $(EMHOME)/lib/em_cemcom $(EMHOME)/man/em_cemcom.6
cp $(CURRDIR)/main $(EMHOME)/lib/em_cemcom
@ -162,6 +179,10 @@ lint: Cfiles
sh -c 'if $(CC) nmclash.c > /dev/null 2>&1 ; then make "EMHOME="$(EMHOME) Xlint ; else sh Resolve Xlint ; fi'
@rm -f nmclash.o a.out
mylint: Cfiles
sh -c 'if $(CC) nmclash.c > /dev/null 2>&1 ; then make "EMHOME="$(EMHOME) Xmylint ; else sh Resolve Xmylint ; fi'
@rm -f nmclash.o a.out
longnames: $(SRC) $(HFILES)
sh -c 'if test -f longnames ; then : ; else touch longnames ; fi ; $(PRID) -l7 longnames $? > Xlongnames ; mv Xlongnames longnames'
@ -208,6 +229,9 @@ switch.h: make.allocd
type.h: make.allocd
estack.h: make.allocd
util.h: make.allocd
l_brace.h: make.allocd
l_state.h: make.allocd
l_outdef.h: make.allocd
depend: Cfiles
sed '/^#AUTOAUTO/,$$d' Makefile >Makefile.new
@ -234,8 +258,15 @@ $(CURRDIR)/cemain: $(OBJ) $(CURRDIR)/Makefile
$(CC) $(COPTIONS) $(LDFLAGS) $(OBJ) $(CELIBS) -o $(CURRDIR)/cemain
size $(CURRDIR)/cemain
Xlint:
lint $(CDEFS) $(LINTFLAGS) $(SRC)
$(CURRDIR)/lnt: $(OBJ) $(CURRDIR)/Makefile
$(CC) $(COPTIONS) $(LDFLAGS) $(OBJ) $(LLIBS) -o $(CURRDIR)/lnt
size $(CURRDIR)/lnt
Xlint: $(SRC)
$(LINT) $(CDEFS) $(LINTFLAGS) $(SRC)
Xmylint: $(SRC)
$(MYLINT) $(CDEFS) $(MYLINTFLAGS) $(SRC)
#AUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTO
main.o: LLlex.h
@ -249,6 +280,7 @@ main.o: idf.h
main.o: input.h
main.o: inputtype.h
main.o: level.h
main.o: lint.h
main.o: noRoption.h
main.o: nobitfield.h
main.o: nocross.h
@ -276,6 +308,7 @@ idf.o: idf.h
idf.o: idfsize.h
idf.o: label.h
idf.o: level.h
idf.o: lint.h
idf.o: noRoption.h
idf.o: nobitfield.h
idf.o: nocross.h
@ -305,9 +338,12 @@ declarator.o: target_sizes.h
declarator.o: type.h
decspecs.o: Lpars.h
decspecs.o: arith.h
decspecs.o: assert.h
decspecs.o: debug.h
decspecs.o: decspecs.h
decspecs.o: def.h
decspecs.o: level.h
decspecs.o: lint.h
decspecs.o: noRoption.h
decspecs.o: nobitfield.h
decspecs.o: nofloat.h
@ -325,6 +361,7 @@ struct.o: field.h
struct.o: file_info.h
struct.o: idf.h
struct.o: level.h
struct.o: lint.h
struct.o: noRoption.h
struct.o: nobitfield.h
struct.o: nocross.h
@ -348,6 +385,7 @@ expr.o: file_info.h
expr.o: idf.h
expr.o: label.h
expr.o: level.h
expr.o: lint.h
expr.o: noRoption.h
expr.o: nobitfield.h
expr.o: nocross.h
@ -365,6 +403,7 @@ ch7.o: def.h
ch7.o: expr.h
ch7.o: idf.h
ch7.o: label.h
ch7.o: lint.h
ch7.o: nobitfield.h
ch7.o: nofloat.h
ch7.o: nopp.h
@ -401,7 +440,6 @@ cstoper.o: target_sizes.h
cstoper.o: type.h
arith.o: Lpars.h
arith.o: arith.h
arith.o: botch_free.h
arith.o: expr.h
arith.o: field.h
arith.o: idf.h
@ -427,8 +465,10 @@ code.o: def.h
code.o: expr.h
code.o: file_info.h
code.o: idf.h
code.o: l_lint.h
code.o: label.h
code.o: level.h
code.o: lint.h
code.o: noRoption.h
code.o: nobitfield.h
code.o: nocross.h
@ -450,6 +490,7 @@ dumpidf.o: expr.h
dumpidf.o: field.h
dumpidf.o: idf.h
dumpidf.o: label.h
dumpidf.o: lint.h
dumpidf.o: nobitfield.h
dumpidf.o: nofloat.h
dumpidf.o: nopp.h
@ -461,10 +502,12 @@ dumpidf.o: type.h
error.o: LLlex.h
error.o: arith.h
error.o: debug.h
error.o: def.h
error.o: errout.h
error.o: expr.h
error.o: file_info.h
error.o: label.h
error.o: lint.h
error.o: nofloat.h
error.o: nopp.h
error.o: spec_arith.h
@ -479,6 +522,7 @@ field.o: expr.h
field.o: field.h
field.o: idf.h
field.o: label.h
field.o: lint.h
field.o: nobitfield.h
field.o: nocross.h
field.o: nofloat.h
@ -507,6 +551,7 @@ LLlex.o: file_info.h
LLlex.o: idf.h
LLlex.o: idfsize.h
LLlex.o: input.h
LLlex.o: lint.h
LLlex.o: nocross.h
LLlex.o: nofloat.h
LLlex.o: nopp.h
@ -575,6 +620,7 @@ options.o: class.h
options.o: dataflow.h
options.o: idf.h
options.o: idfsize.h
options.o: lint.h
options.o: macro.h
options.o: noRoption.h
options.o: nobitfield.h
@ -610,6 +656,7 @@ stack.o: debug.h
stack.o: def.h
stack.o: idf.h
stack.o: level.h
stack.o: lint.h
stack.o: mes.h
stack.o: noRoption.h
stack.o: nobitfield.h
@ -625,6 +672,7 @@ type.o: arith.h
type.o: botch_free.h
type.o: def.h
type.o: idf.h
type.o: lint.h
type.o: nobitfield.h
type.o: nocross.h
type.o: nofloat.h
@ -640,6 +688,7 @@ ch7mon.o: def.h
ch7mon.o: expr.h
ch7mon.o: idf.h
ch7mon.o: label.h
ch7mon.o: lint.h
ch7mon.o: nobitfield.h
ch7mon.o: nofloat.h
ch7mon.o: nopp.h
@ -651,6 +700,7 @@ label.o: def.h
label.o: idf.h
label.o: label.h
label.o: level.h
label.o: lint.h
label.o: noRoption.h
label.o: nobitfield.h
label.o: nofloat.h
@ -670,6 +720,7 @@ eval.o: expr.h
eval.o: idf.h
eval.o: label.h
eval.o: level.h
eval.o: lint.h
eval.o: mes.h
eval.o: nobitfield.h
eval.o: nocross.h
@ -700,6 +751,7 @@ switch.o: switch.h
switch.o: type.h
conversion.o: Lpars.h
conversion.o: arith.h
conversion.o: lint.h
conversion.o: nobitfield.h
conversion.o: nocross.h
conversion.o: nofloat.h
@ -710,6 +762,7 @@ conversion.o: type.h
util.o: Lpars.h
util.o: align.h
util.o: def.h
util.o: lint.h
util.o: nocross.h
util.o: nofloat.h
util.o: regcount.h
@ -723,6 +776,7 @@ blocks.o: align.h
blocks.o: arith.h
blocks.o: atw.h
blocks.o: label.h
blocks.o: lint.h
blocks.o: nocross.h
blocks.o: nofloat.h
blocks.o: sizes.h
@ -730,10 +784,116 @@ blocks.o: spec_arith.h
blocks.o: stack.h
blocks.o: target_sizes.h
dataflow.o: dataflow.h
l_lint.o: LLlex.h
l_lint.o: Lpars.h
l_lint.o: arith.h
l_lint.o: code.h
l_lint.o: def.h
l_lint.o: expr.h
l_lint.o: file_info.h
l_lint.o: idf.h
l_lint.o: l_lint.h
l_lint.o: l_outdef.h
l_lint.o: l_state.h
l_lint.o: label.h
l_lint.o: level.h
l_lint.o: lint.h
l_lint.o: nobitfield.h
l_lint.o: nofloat.h
l_lint.o: nopp.h
l_lint.o: spec_arith.h
l_lint.o: stack.h
l_lint.o: type.h
l_states.o: LLlex.h
l_states.o: Lpars.h
l_states.o: arith.h
l_states.o: assert.h
l_states.o: code.h
l_states.o: debug.h
l_states.o: def.h
l_states.o: expr.h
l_states.o: file_info.h
l_states.o: idf.h
l_states.o: l_brace.h
l_states.o: l_lint.h
l_states.o: l_outdef.h
l_states.o: l_state.h
l_states.o: label.h
l_states.o: level.h
l_states.o: lint.h
l_states.o: nobitfield.h
l_states.o: nofloat.h
l_states.o: nopp.h
l_states.o: spec_arith.h
l_states.o: stack.h
l_states.o: type.h
l_misc.o: LLlex.h
l_misc.o: Lpars.h
l_misc.o: arith.h
l_misc.o: code.h
l_misc.o: def.h
l_misc.o: expr.h
l_misc.o: file_info.h
l_misc.o: idf.h
l_misc.o: l_state.h
l_misc.o: label.h
l_misc.o: level.h
l_misc.o: lint.h
l_misc.o: nobitfield.h
l_misc.o: nofloat.h
l_misc.o: nopp.h
l_misc.o: spec_arith.h
l_misc.o: stack.h
l_misc.o: type.h
l_ev_ord.o: LLlex.h
l_ev_ord.o: Lpars.h
l_ev_ord.o: arith.h
l_ev_ord.o: code.h
l_ev_ord.o: def.h
l_ev_ord.o: expr.h
l_ev_ord.o: file_info.h
l_ev_ord.o: idf.h
l_ev_ord.o: l_lint.h
l_ev_ord.o: l_state.h
l_ev_ord.o: label.h
l_ev_ord.o: level.h
l_ev_ord.o: lint.h
l_ev_ord.o: nobitfield.h
l_ev_ord.o: nofloat.h
l_ev_ord.o: nopp.h
l_ev_ord.o: spec_arith.h
l_ev_ord.o: stack.h
l_ev_ord.o: type.h
l_outdef.o: LLlex.h
l_outdef.o: Lpars.h
l_outdef.o: arith.h
l_outdef.o: def.h
l_outdef.o: expr.h
l_outdef.o: field.h
l_outdef.o: file_info.h
l_outdef.o: idf.h
l_outdef.o: l_class.h
l_outdef.o: l_lint.h
l_outdef.o: l_outdef.h
l_outdef.o: label.h
l_outdef.o: level.h
l_outdef.o: lint.h
l_outdef.o: nobitfield.h
l_outdef.o: nofloat.h
l_outdef.o: nopp.h
l_outdef.o: spec_arith.h
l_outdef.o: stack.h
l_outdef.o: struct.h
l_outdef.o: type.h
l_comment.o: arith.h
l_comment.o: l_state.h
l_comment.o: lint.h
l_comment.o: spec_arith.h
tokenfile.o: Lpars.h
declar.o: LLlex.h
declar.o: Lpars.h
declar.o: arith.h
declar.o: code.h
declar.o: debug.h
declar.o: declar.h
declar.o: decspecs.h
@ -742,8 +902,11 @@ declar.o: expr.h
declar.o: field.h
declar.o: file_info.h
declar.o: idf.h
declar.o: l_lint.h
declar.o: l_state.h
declar.o: label.h
declar.o: level.h
declar.o: lint.h
declar.o: nobitfield.h
declar.o: nocross.h
declar.o: nofloat.h
@ -763,7 +926,10 @@ statement.o: def.h
statement.o: expr.h
statement.o: file_info.h
statement.o: idf.h
statement.o: l_lint.h
statement.o: l_state.h
statement.o: label.h
statement.o: lint.h
statement.o: nobitfield.h
statement.o: nofloat.h
statement.o: nopp.h
@ -773,10 +939,12 @@ statement.o: type.h
expression.o: LLlex.h
expression.o: Lpars.h
expression.o: arith.h
expression.o: code.h
expression.o: expr.h
expression.o: file_info.h
expression.o: idf.h
expression.o: label.h
expression.o: lint.h
expression.o: noRoption.h
expression.o: nobitfield.h
expression.o: nofloat.h
@ -793,7 +961,9 @@ program.o: def.h
program.o: expr.h
program.o: file_info.h
program.o: idf.h
program.o: l_state.h
program.o: label.h
program.o: lint.h
program.o: nobitfield.h
program.o: nofloat.h
program.o: nopp.h
@ -804,6 +974,7 @@ ival.o: LLlex.h
ival.o: Lpars.h
ival.o: arith.h
ival.o: assert.h
ival.o: code.h
ival.o: debug.h
ival.o: def.h
ival.o: estack.h
@ -811,8 +982,10 @@ ival.o: expr.h
ival.o: field.h
ival.o: file_info.h
ival.o: idf.h
ival.o: l_lint.h
ival.o: label.h
ival.o: level.h
ival.o: lint.h
ival.o: noRoption.h
ival.o: nobitfield.h
ival.o: nocross.h

View file

@ -1,3 +1,7 @@
!File: lint.h
#undef LINT 1 /* if defined, 'lint' is produced */
!File: pathlength.h
#define PATHLENGTH 1024 /* max. length of path to file */

View file

@ -12,7 +12,7 @@ esac
PW=`pwd`
options=
case $1 in
main|emain)
main|emain|lnt)
target=$PW/$1
;;
omain)

View file

@ -5,6 +5,9 @@
/* $Header$ */
/* B L O C K S T O R I N G A N D L O A D I N G */
#include "lint.h"
#ifndef LINT
#include <em.h>
#include <em_reg.h>
#include "arith.h"
@ -161,3 +164,5 @@ copy_loop(sz, src, dst)
}
#endif STB
#endif LINT

View file

@ -5,6 +5,7 @@
/* $Header$ */
/* S E M A N T I C A N A L Y S I S -- C H A P T E R 7 RM */
#include "lint.h"
#include "nofloat.h"
#include "debug.h"
#include "nobitfield.h"
@ -218,6 +219,10 @@ ch7cast(expp, oper, tp)
if (oper != CAST)
expr_warning(*expp, "incompatible pointers in %s",
symbol2str(oper));
#ifdef LINT
if (oper == CAST)
lint_ptr_conv(oldtp->tp_up->tp_fund, tp->tp_up->tp_fund);
#endif LINT
(*expp)->ex_type = tp; /* free conversion */
}
else

View file

@ -5,6 +5,7 @@
/* $Header$ */
/* C O D E - G E N E R A T I N G R O U T I N E S */
#include "lint.h"
#include <em.h>
#include "botch_free.h"
#include <alloc.h>
@ -29,6 +30,10 @@
#include "assert.h"
#include "noRoption.h"
#include "file_info.h"
#ifdef LINT
#include "l_lint.h"
#endif LINT
label lab_count = 1;
label datlab_count = 1;
@ -49,6 +54,7 @@ static int pro_id;
extern char options[];
extern char *symbol2str();
#ifndef LINT
init_code(dst_file)
char *dst_file;
{
@ -64,6 +70,8 @@ init_code(dst_file)
C_insertpart(tmp_id = C_getid());
#endif USE_TMP
}
#endif LINT
static struct string_cst *str_list = 0;
code_string(val, len, dlb)
@ -262,6 +270,7 @@ end_proc(fbytes)
if (return_expr_occurred) C_asp(-func_size);
C_df_ilb(return_label);
prc_exit();
#ifndef LINT
if (return_expr_occurred) {
if (func_res_label != 0) {
C_lae_dlb(func_res_label, (arith)0);
@ -273,6 +282,8 @@ end_proc(fbytes)
C_ret(func_size);
}
else C_ret((arith) 0);
#endif LINT
/* getting the number of "local" bytes is posponed until here,
because copying the function result in "func_res_label" may
need temporaries! However, local_level is now L_FORMAL2, because
@ -466,6 +477,7 @@ loc_init(expr, id)
}
else { /* not embraced */
ch7cast(&expr, '=', tp); /* may modify expr */
#ifndef LINT
{
struct value vl;
@ -475,6 +487,9 @@ loc_init(expr, id)
vl.vl_value = (arith)0;
store_val(&vl, tp);
}
#else LINT
id->id_def->df_set = 1;
#endif LINT
free_expression(expr);
}
}
@ -522,6 +537,9 @@ formal_cvt(df)
}
}
#ifdef LINT
/*ARGSUSED*/
#endif LINT
code_expr(expr, val, code, tlbl, flbl)
struct expr *expr;
label tlbl, flbl;
@ -530,9 +548,13 @@ code_expr(expr, val, code, tlbl, flbl)
generator. If line number trace is wanted, it generates a
lin instruction. EVAL() is called directly.
*/
#ifndef LINT
if (! options['L']) /* profiling */
C_lin((arith)(expr->ex_line));
EVAL(expr, val, code, tlbl, flbl);
#else LINT
pre_lint_expr(expr, RVAL, code ? USED : IGNORED);
#endif LINT
}
/* The FOR/WHILE/DO/SWITCH stacking mechanism:

View file

@ -5,6 +5,9 @@
/* $Header$ */
/* C O N V E R S I O N - C O D E G E N E R A T O R */
#include "lint.h"
#ifndef LINT
#include "nofloat.h"
#include <em.h>
#include "arith.h"
@ -149,3 +152,5 @@ convtype(tp)
return 0;
}
#endif LINT

View file

@ -6,6 +6,7 @@
/* DECLARATION SYNTAX PARSER */
{
#include "lint.h"
#include <alloc.h>
#include "nobitfield.h"
#include "debug.h"
@ -24,6 +25,11 @@
#include "expr.h"
#include "sizes.h"
#include "level.h"
#ifdef LINT
#include "l_lint.h"
#include "l_state.h"
#endif LINT
extern char options[];
}
@ -158,6 +164,9 @@ init_declarator(register struct decspecs *ds;)
{
reject_params(&Dc);
declare_idf(ds, &Dc, level);
#ifdef LINT
lint_declare_idf(Dc.dc_idf, ds->ds_sc);
#endif LINT
}
[
initializer(Dc.dc_idf, ds->ds_sc)
@ -166,6 +175,9 @@ init_declarator(register struct decspecs *ds;)
]
]
{
#ifdef LINT
add_auto(Dc.dc_idf);
#endif LINT
remove_declarator(&Dc);
}
;
@ -193,6 +205,9 @@ initializer(struct idf *idf; int sc;)
*/
]
{
#ifdef LINT
lint_statement();
#endif LINT
if (globalflag) {
struct expr ex;
code_declaration(idf, &ex, level, sc);
@ -208,6 +223,10 @@ initializer(struct idf *idf; int sc;)
#ifdef DEBUG
print_expr("initializer-expression", expr);
#endif DEBUG
#ifdef LINT
change_state(idf, SET);
pre_lint_expr(expr, RVAL, USED);
#endif LINT
code_declaration(idf, expr, level, sc);
}
init_idf(idf);

View file

@ -5,6 +5,7 @@
/* $Header$ */
/* IDENTIFIER DEFINITION DESCRIPTOR */
#include "lint.h"
struct def { /* for ordinary tags */
struct def *next;
@ -21,6 +22,11 @@ struct def { /* for ordinary tags */
char df_used; /* set if idf is used */
char *df_file; /* file containing the definition */
unsigned int df_line; /* line number of the definition */
#ifdef LINT
char df_set;
int df_firstbrace; /* brace number of its first occurrence */
int df_minlevel; /* the lowest level needed for this def */
#endif LINT
char df_formal_array; /* to warn if sizeof is taken */
arith df_address;
};

View file

@ -9,6 +9,7 @@
#include <system.h>
#include <em.h>
#include "lint.h"
#include "nopp.h"
#include "errout.h"
#include "debug.h"
@ -34,6 +35,10 @@
int err_occurred = 0;
extern char options[];
#ifdef LINT
extern char loptions[];
#endif LINT
/* There are three general error-message functions:
lexerror() lexical and pre-processor error messages
error() syntactic and semantic error messages
@ -110,6 +115,54 @@ expr_warning(va_alist) /* expr, fmt, args */
va_end(ap);
}
#ifdef LINT
/*VARARGS*/
def_warning(va_alist) /* def, fmt, args */
va_dcl
{
va_list ap;
va_start(ap);
{
register struct def *def = va_arg(ap, struct def *);
_error(WARNING, def->df_file, def->df_line, ap);
}
va_end(ap);
}
/*VARARGS*/
hwarning(va_alist) /* fmt, args */
va_dcl
{
va_list ap;
va_start(ap);
{
if (loptions['h'])
_error(WARNING, dot.tk_file, dot.tk_line, ap);
}
va_end(ap);
}
/*VARARGS*/
awarning(va_alist) /* fmt, args */
va_dcl
{
va_list ap;
va_start(ap);
{
if (loptions['a'])
_error(WARNING, dot.tk_file, dot.tk_line, ap);
}
va_end(ap);
}
#endif LINT
/*VARARGS*/
lexerror(va_alist) /* fmt, args */
va_dcl
@ -186,9 +239,11 @@ _error(class, fn, ln, ap)
/* _error attempts to limit the number of error messages
for a given line to MAXERR_LINE.
*/
#ifndef LINT
static char *last_fn = 0;
static unsigned int last_ln = 0;
static int e_seen = 0;
#endif LINT
char *remark;
char *fmt = va_arg(ap, char *);
@ -215,7 +270,11 @@ _error(class, fn, ln, ap)
/* the remark */
switch (class) {
case WARNING:
#ifndef LINT
remark = "(warning)";
#else LINT
remark = 0;
#endif LINT
break;
case ERROR:
@ -233,6 +292,7 @@ _error(class, fn, ln, ap)
/*NOTREACHED*/;
}
#ifndef LINT
if (ln == last_ln && fn && last_fn && strcmp(fn, last_fn) == 0) {
/* we've seen this place before */
e_seen++;
@ -249,6 +309,20 @@ _error(class, fn, ln, ap)
last_ln = ln;
e_seen = 0;
}
#endif LINT
#ifdef LINT
if ( /* there is a file name */
fn
&& /* the file name is global */
fn[0] == '/'
&& /* it is not a .c file */
strcmp(&fn[strlen(fn)-2], ".c") != 0
) {
/* we skip this message */
return;
}
#endif LINT
if (fn)
fprint(ERROUT, "\"%s\", line %u: ", fn, ln);

View file

@ -5,6 +5,9 @@
/* $Header$ */
/* EXPRESSION-CODE GENERATOR */
#include "lint.h"
#ifndef LINT
#include "nofloat.h"
#include <em.h>
#include <em_reg.h>
@ -969,3 +972,5 @@ load_cst(val, siz)
}
}
#endif LINT

View file

@ -5,6 +5,7 @@
/* $Header$ */
/* EXPRESSION TREE HANDLING */
#include "lint.h"
#include "nofloat.h"
#include "botch_free.h"
#include <alloc.h>
@ -181,7 +182,9 @@ idf2expr(expr)
expr->ex_type = error_type;
}
else {
#ifndef LINT
def->df_used = 1;
#endif LINT
expr->ex_type = def->df_type;
if (expr->ex_type == error_type)
expr->ex_flags |= EX_ERROR;
@ -196,12 +199,14 @@ idf2expr(expr)
expr->VL_CLASS = Const;
expr->VL_VALUE = def->df_address;
}
#ifndef LINT
else
if (def->df_sc == STATIC && def->df_level >= L_LOCAL) {
expr->VL_CLASS = Label;
expr->VL_LBL = def->df_address;
expr->VL_VALUE = (arith)0;
}
#endif LINT
else {
expr->VL_CLASS = Name;
expr->VL_IDF = idf;

View file

@ -6,6 +6,7 @@
/* EXPRESSION SYNTAX PARSER */
{
#include "lint.h"
#include "arith.h"
#include "LLlex.h"
#include "type.h"
@ -207,6 +208,10 @@ conditional_expression(struct expr **expp;)
#endif
ch7bin(&e1, ':', e2);
opnd2test(expp, '?');
#ifdef LINT
if (is_cp_cst(*expp))
hwarning("condition in ?: is constant");
#endif LINT
ch7bin(expp, '?', e1);
}
]?

View file

@ -5,6 +5,9 @@
/* $Header$ */
/* BITFIELD EXPRESSION EVALUATOR */
#include "lint.h"
#ifndef LINT
#include "nobitfield.h"
#ifndef NOBITFIELD
@ -174,3 +177,5 @@ eval_field(expr, code)
}
#endif NOBITFIELD
#endif LINT

View file

@ -5,6 +5,7 @@
/* $Header$ */
/* IDENTIFIER FIDDLING & SYMBOL TABLE HANDLING */
#include "lint.h"
#include <em_reg.h>
#include "nofloat.h"
#include "debug.h"
@ -266,6 +267,22 @@ declare_idf(ds, dc, lvl)
}
#endif
#ifdef LINT
if ( def && def->df_level < lvl
&& !(lvl == L_FORMAL2 || def->df_level == L_UNIVERSAL)
) {
/* there is already a definition for this name
on a more global level
*/
warning("%s is already defined as a %s",
idf->id_text,
def->df_level == L_GLOBAL ? "global" :
def->df_level == L_FORMAL2 ? "formal" :
"more global local"
);
}
#endif LINT
if (def &&
( def->df_level == lvl ||
( lvl != L_GLOBAL && def->df_level > lvl )
@ -326,6 +343,11 @@ declare_idf(ds, dc, lvl)
newdef->df_sc = sc;
newdef->df_file = idf->id_file;
newdef->df_line = idf->id_line;
#ifdef LINT
newdef->df_set = (type->tp_fund == ARRAY);
newdef->df_firstbrace = 0;
#endif LINT
/* link it into the name list in the proper place */
idf->id_def = newdef;
update_ahead(idf);

View file

@ -6,6 +6,7 @@
/* CODE FOR THE INITIALISATION OF GLOBAL VARIABLES */
{
#include "lint.h"
#include "nofloat.h"
#include <em.h>
#include "debug.h"
@ -27,6 +28,10 @@
#include "noRoption.h"
#include "estack.h"
#include "code.h"
#ifdef LINT
#include "l_lint.h"
#endif LINT
#define con_nullbyte() C_con_ucon("0", (arith)1)
#define aggregate_type(tp) ((tp)->tp_fund == ARRAY || (tp)->tp_fund == STRUCT)
@ -48,6 +53,9 @@ initial_value(register struct type **tpp; register struct expr **expp;) :
[
assignment_expression(expp)
{
#ifdef LINT
pre_lint_expr(*expp, RVAL, USED);
#endif LINT
if ((*expp)->ex_type->tp_fund == ARRAY)
array2pointer(*expp);
if (tpp) {

21
lang/cem/cemcom/l_class.h Normal file
View file

@ -0,0 +1,21 @@
/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/* Lint class constants */
#define LFDF 'a' /* Library Function Definition */
#define LVDF 'b' /* Library Variable Definition */
#define EFDF 'c' /* External Function Definition */
#define EVDF 'd' /* External Variable Definition */
#define EFDC 'e' /* External Function Declaration */
#define EVDC 'f' /* External Variable Declaration */
#define IFDC 'g' /* Implicit Function Declaration */
#define SFDF 'h' /* Static Function Definition */
#define SVDF 'i' /* Static Variable Definition */
#define FC 'j' /* Function Call */
#define VU 'k' /* Variable Usage */
#define XXDF 'l' /* Ignore Class */

129
lang/cem/cemcom/l_comment.c Normal file
View file

@ -0,0 +1,129 @@
/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/* Lint-specific comment handling */
#include "lint.h"
#ifdef LINT
#include "arith.h"
#include "l_state.h"
static int NOTREACHED;
static int VARARGSn = -1;
static int ARGSUSED;
int LINTLIB;
int s_NOTREACHED;
int f_VARARGSn;
int f_ARGSUSED;
set_not_reached()
{
NOTREACHED = 1;
}
move_NOT2s()
{
s_NOTREACHED = NOTREACHED;
NOTREACHED = 0;
}
set_varargs(n)
{
VARARGSn = n;
}
move_VAR2f()
{
f_VARARGSn = VARARGSn;
VARARGSn = -1;
}
set_argsused(n)
{
ARGSUSED = n;
}
move_ARG2f()
{
f_ARGSUSED = ARGSUSED;
ARGSUSED = 0;
}
set_lintlib()
{
LINTLIB = 1;
}
#define IN_SPACE 0
#define IN_WORD 1
#define IN_COMMENT 2
lint_comment(c)
int c;
{
/* This function is called with every character between /_* and *_/ (the
* _underscores are used because comment in C doesn't nest).
* It looks for pseudocomments.
* In this version it is allowed that 'keyword' is followed by rubbish.
* At the start of each comment the function should be initialized by
* calling it with c = -2.
* I am not sure if this way of information hiding is a good solution.
*/
static int position; /* IN_SPACE, IN_WORD, IN_COMMENT */
static char buf[12];
static int i; /* next free position in buf */
if (c == -2) {
position = IN_SPACE;
i = 0;
return;
}
if (position == IN_COMMENT)
return;
if (position == IN_SPACE) {
if (c == ' ' || c == '\t')
return;
position = IN_WORD;
}
/* position == IN_WORD */
if (c == ' ' || c == '\t' || c == '*') {
position = IN_COMMENT;
check_pseudo(buf, i);
}
else
if (i < 12)
buf[i++] = (char)c;
else
position = IN_COMMENT;
}
#include <ctype.h>
check_pseudo(buf, i)
char *buf;
{
/* Look if the i characters in buf are aequivalent with one of the
* strings N_OTREACHED, V_ARARGS[n], A_RGSUSED, L_INTLIBRARY
* (the u_nderscores are there to not confuse (UNIX) lint)
*/
buf[i++] = '\0';
if (!strcmp(buf, "NOTREACHED"))
set_not_reached();
else if (!strcmp(buf, "ARGSUSED"))
set_argsused(1);
else if (!strcmp(buf, "LINTLIBRARY"))
set_lintlib();
else if (!strncmp(buf, "VARARGS", 7)) {
if (i == 8)
set_varargs(0);
else if (i == 9 && isdigit(buf[7]))
set_varargs(atoi(&buf[7]));
}
}
#endif LINT

63
lang/cem/cemcom/l_dummy.c Normal file
View file

@ -0,0 +1,63 @@
/*
*The following functions are hacked to null-functions (i.e. they
* do nothing). This needs another solution in the future.
*/
#include "arith.h"
#include "label.h"
C_close(){}
int C_busy(){return 0;}
/* More routines */
/* ARGSUSED */
CC_bhcst(ps_xxx,n,w,i) arith n,w; {}
/* ARGSUSED */
CC_crcst(ps_xxx,v) arith v; {}
/* ARGSUSED */
CC_crdlb(ps_xxx,v,s) label v; arith s; {}
/* ARGSUSED */
CC_crdnam(ps_xxx,v,s) char *v; arith s; {}
/* ARGSUSED */
CC_crfcon(ps_xxx,v,s) char *v; arith s; {}
/* ARGSUSED */
CC_cricon(ps_xxx,v,s) char *v; arith s; {}
/* ARGSUSED */
CC_crilb(ps_xxx,v) label v; {}
/* ARGSUSED */
CC_crpnam(ps_xxx,v) char *v; {}
/* ARGSUSED */
CC_crscon(ps_xxx,v,s) char *v; arith s; {}
/* ARGSUSED */
CC_crucon(ps_xxx,v,s) char *v; arith s; {}
/* ARGSUSED */
CC_cst(l) {}
/* ARGSUSED */
CC_dfdlb(l) label l; {}
/* ARGSUSED */
CC_dfdnam(s) char *s; {}
/* ARGSUSED */
CC_dfilb(l) label l; {}
/* ARGSUSED */
CC_end(l) arith l; {}
CC_msend() {}
/* ARGSUSED */
CC_msstart(ms) {}
/* ARGSUSED */
CC_opcst(op_xxx,c) arith c; {}
/* ARGSUSED */
CC_opdlb(op_xxx,g,o) label g; arith o; {}
/* ARGSUSED */
CC_opilb(op_xxx,b) label b; {}
/* ARGSUSED */
CC_oppnam(op_xxx,p) char *p; {}
/* ARGSUSED */
CC_pronarg(s) char *s; {}
/* ARGSUSED */
CC_psdlb(ps_xxx,l) label l; {}
/* ARGSUSED */
CC_psdnam(ps_xxx,s) char *s; {}
/* ARGSUSED */
CC_pspnam(ps_xxx,s) char *s; {}
/* ARGSUSED */
CC_scon(v,s) char *s; {}

118
lang/cem/cemcom/l_ev_ord.c Normal file
View file

@ -0,0 +1,118 @@
/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/* Lint evaluation order checking */
#include "lint.h"
#ifdef LINT
#include <alloc.h> /* for st_free */
#include "arith.h" /* definition arith */
#include "label.h" /* definition label */
#include "expr.h"
#include "idf.h"
#include "def.h"
#include "code.h" /* RVAL etc */
#include "LLlex.h"
#include "Lpars.h"
#include "stack.h"
#include "type.h"
#include "level.h"
#include "nofloat.h"
#include "l_lint.h"
#include "l_state.h"
extern char *symbol2str();
check_and_merge(espp, esp, com_oper)
struct expr_state **espp, *esp;
{
/* Checks for undefined evaluation orders in case of a commutative operator.
* In addition the sets of used and set variables of both expressions are
* united.
* *espp will be pointing to this new list. esp is used for this list.
*/
register struct expr_state **pp, *p1, *p2;
for (p1 = *espp; p1; p1 = p1->next) {
p2 = esp;
pp = &esp;
while (p2) {
if ( /* p1 and p2 are the same */
p1->es_idf == p2->es_idf
&& p1->es_offset == p2->es_offset
) {
if (com_oper)
check_ev_order(p1, p2, com_oper);
p1->es_used |= p2->es_used;
p1->es_set |= p2->es_set;
*pp = p2->next;
free_expr_state(p2);
p2 = *pp;
}
else {
pp = &p2->next;
p2 = p2->next;
}
}
}
/* The rest of the list esp is pointing to, is put in front of the list
* *espp is now pointing to.
* *espp will be pointing to this new list.
*/
if (!esp)
return;
p1 = *espp;
*espp = esp;
while (esp->next)
esp = esp->next;
esp->next = p1;
}
check_ev_order(esp1, esp2, com_oper)
struct expr_state *esp1, *esp2;
{
if ( (esp1->es_used && esp2->es_set)
|| (esp1->es_set && esp2->es_used)
|| (esp1->es_set && esp2->es_set)
) {
warning("result of %s depends on evaluation order on %s",
symbol2str(com_oper),
esp1->es_idf->id_text);
}
}
add_expr_state(value, to_state, espp)
struct value value;
struct expr_state **espp;
{
register struct expr_state *esp = *espp;
if (value.vl_class != Name) {
crash("(add_expr_state) invalid vl_class");
/*NOTREACHED*/
}
while ( esp
&& !( esp->es_idf == value.vl_data.vl_idf
&& esp->es_offset == value.vl_value
)
) {
esp = esp->next;
}
if (!esp) { /* create new expr_state */
esp = new_expr_state();
esp->es_idf = value.vl_data.vl_idf;
esp->es_offset = value.vl_value;
esp->next = *espp;
*espp = esp;
}
if (to_state == SET)
esp->es_set = 1;
else /* USED */
esp->es_used = 1;
}
#endif LINT

350
lang/cem/cemcom/l_lint.c Normal file
View file

@ -0,0 +1,350 @@
/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/* Lint main routines */
#include "lint.h"
#ifdef LINT
#include <alloc.h> /* for st_free */
#include "arith.h" /* definition arith */
#include "label.h" /* definition label */
#include "expr.h"
#include "idf.h"
#include "def.h"
#include "code.h" /* RVAL etc */
#include "LLlex.h"
#include "Lpars.h"
#include "stack.h"
#include "type.h"
#include "level.h"
#include "nofloat.h"
#include "l_lint.h"
#include "l_state.h"
#include "l_outdef.h"
extern char options[128];
extern char *symbol2str();
struct expr_state *lint_expr();
lint_init()
{
/* Allocate some memory for the global stack_bottom
* and some other initializations
*/
extern struct lint_stack_entry stack_bottom;
stack_bottom.ls_current = new_state();
}
pre_lint_expr(expr, val, used)
struct expr *expr;
{
/* Introduced to dispose the returned expression states */
register struct expr_state *esp;
esp = lint_expr(expr, val, used);
free_expr_states(esp);
}
free_expr_states(esp)
register struct expr_state *esp;
{
register struct expr_state *esp2;
while (esp) {
esp2 = esp;
esp = esp->next;
free_expr_state(esp2);
}
}
struct expr_state *
lint_expr(expr, val, used)
register struct expr *expr;
{
/* Main function to process an expression tree.
* It returns a structure containing information about which variables
* are set and which are used in the expression.
* In addition it sets 'used' and 'set' fields of the corresponding
* variables in the current state.
* If the value of an operation without side-effects is not used,
* a warning is given.
*/
struct expr_state *esp1 = 0, *esp2 = 0;
if (used == IGNORED) {
expr_ignored(expr);
}
switch (expr->ex_class) {
case Value:
switch (expr->VL_CLASS) {
case Const:
case Label:
return(0);
case Name:
{
register struct idf *idf = expr->VL_IDF;
if (!idf || !idf->id_def)
return(0);
if ( val == LVAL
|| ( val == RVAL
&& expr->ex_type->tp_fund == POINTER
&& !expr->ex_lvalue
)
) {
change_state(idf, SET);
idf->id_def->df_file =
Salloc(dot.tk_file,
strlen(dot.tk_file) + 1);
idf->id_def->df_line = dot.tk_line;
}
if (val == RVAL) {
change_state(idf, USED);
add_expr_state(expr->EX_VALUE, USED, &esp1);
}
return(esp1);
}
default:
crash("(lint_expr) bad value class\n");
/* NOTREACHED */
}
case Oper:
{
register int oper = expr->OP_OPER;
register struct expr *left = expr->OP_LEFT;
register struct expr *right = expr->OP_RIGHT;
switch (oper) {
case '=':
case PLUSAB:
case MINAB:
case TIMESAB:
case DIVAB:
case MODAB:
case LEFTAB:
case RIGHTAB:
case ANDAB:
case XORAB:
case ORAB:
lint_conversion(oper, right->ex_type, left->ex_type);
/* for cases like i += l; */
esp1 = lint_expr(right, RVAL, USED);
if (oper != '=') {
/* i += 1; is interpreted as i = i + 1; */
esp2 = lint_expr(left, RVAL, USED);
check_and_merge(&esp1, esp2, oper);
}
esp2 = lint_expr(left, LVAL, USED);
/* for cases like i = i + 1; and i not set, this
** order is essential
*/
check_and_merge(&esp1, esp2, oper);
if ( left->ex_class == Value
&& left->VL_CLASS == Name
) {
add_expr_state(left->EX_VALUE, SET, &esp1);
}
return(esp1);
case POSTINCR:
case POSTDECR:
case PLUSPLUS:
case MINMIN:
/* i++; is parsed as i = i + 1;
* This isn't quite correct :
* The first statement doesn't USE i,
* the second does.
*/
esp1 = lint_expr(left, RVAL, USED);
esp2 = lint_expr(left, LVAL, USED);
check_and_merge(&esp1, esp2, oper);
if ( left->ex_class == Value
&& left->VL_CLASS == Name
) {
add_expr_state(left->EX_VALUE, SET, &esp1);
add_expr_state(left->EX_VALUE, USED, &esp1);
}
return(esp1);
case '-':
case '*':
if (left == 0) /* unary */
return(lint_expr(right, RVAL, USED));
esp1 = lint_expr(left, RVAL, USED);
esp2 = lint_expr(right, RVAL, USED);
check_and_merge(&esp1, esp2, oper);
return(esp1);
case '(':
if (right != 0) {
/* function call with parameters */
register struct expr *ex = right;
while ( ex->ex_class == Oper
&& ex->OP_OPER == PARCOMMA
) {
esp2 = lint_expr(ex->OP_RIGHT, RVAL,
USED);
check_and_merge(&esp1, esp2, oper);
ex = ex->OP_LEFT;
}
esp2 = lint_expr(ex, RVAL, USED);
check_and_merge(&esp1, esp2, oper);
}
if ( left->ex_class == Value
&& left->VL_CLASS == Name
) {
fill_outcall(expr,
expr->ex_type->tp_fund == VOID ?
VOIDED : used
);
outcall();
left->VL_IDF->id_def->df_used = 1;
}
else {
esp2 = lint_expr(left, val, USED);
check_and_merge(&esp1, esp2, oper);
}
return(esp1);
case '.':
return(lint_expr(left, val, USED));
case ARROW:
return(lint_expr(left, RVAL, USED));
case '~':
case '!':
return(lint_expr(right, RVAL, USED));
case '?':
esp1 = lint_expr(left, RVAL, USED);
esp2 = lint_expr(right->OP_LEFT, RVAL, USED);
check_and_merge(&esp1, esp2, 0);
esp2 = lint_expr(right->OP_RIGHT, RVAL, USED);
check_and_merge(&esp1, esp2, 0);
return(esp1);
case INT2INT:
case INT2FLOAT:
case FLOAT2INT:
case FLOAT2FLOAT:
lint_conversion(oper, right->ex_type, left->ex_type);
return(lint_expr(right, RVAL, USED));
case '<':
case '>':
case LESSEQ:
case GREATEREQ:
case EQUAL:
case NOTEQUAL:
lint_relop(left, right, oper);
lint_relop(right, left,
oper == '<' ? '>' :
oper == '>' ? '<' :
oper == LESSEQ ? GREATEREQ :
oper == GREATEREQ ? LESSEQ :
oper
);
/*FALLTHROUGH*/
case '+':
case '/':
case '%':
case ',':
case LEFT:
case RIGHT:
case '&':
case '|':
case '^':
case OR:
case AND:
esp1 = lint_expr(left, RVAL,
oper == ',' ? IGNORED : USED);
esp2 = lint_expr(right, RVAL,
oper == ',' ? used : USED);
if (oper == OR || oper == AND || oper == ',')
check_and_merge(&esp1, esp2, 0);
else
check_and_merge(&esp1, esp2, oper);
return(esp1);
default:
return(0); /* for initcomma */
}
}
default:
return(0);
}
}
expr_ignored(expr)
struct expr *expr;
{
switch (expr->ex_class) {
case Oper:
switch (expr->OP_OPER) {
case '=':
case TIMESAB:
case DIVAB:
case MODAB:
case LEFTAB:
case RIGHTAB:
case ANDAB:
case XORAB:
case ORAB:
case AND: /* doubtful but useful */
case OR: /* doubtful but useful */
case '(':
case '?':
case ',':
break;
case PLUSAB:
case MINAB:
case POSTINCR:
case POSTDECR:
case PLUSPLUS:
case MINMIN:
/* may hide the operator * */
if ( /* operation on a pointer */
expr->OP_TYPE->tp_fund == POINTER
&& /* the result is dereferenced, e.g. *p++; */
expr->ex_type == expr->OP_TYPE->tp_up
) {
hwarning("result of * ignored");
}
break;
default:
hwarning("result of %s ignored",
symbol2str(expr->OP_OPER));
break;
}
break;
case Value:
hwarning("identifier as statement");
break;
case String:
case Float:
hwarning("constant as statement");
break;
}
}
#endif LINT

17
lang/cem/cemcom/l_lint.h Normal file
View file

@ -0,0 +1,17 @@
/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/* LINT FLAGS */
#define USED 0
#define IGNORED 1
#define SET 2
#define VOIDED 3
/* for od_valreturned */
#define NOVALRETURNED 0
#define VALRETURNED 1
#define NORETURN 2 /* end of function NOTREACHED */

155
lang/cem/cemcom/l_misc.c Normal file
View file

@ -0,0 +1,155 @@
/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/* Lint miscellaneous routines */
#include "lint.h"
#ifdef LINT
#include <alloc.h> /* for st_free */
#include "arith.h" /* definition arith */
#include "label.h" /* definition label */
#include "expr.h"
#include "idf.h"
#include "def.h"
#include "code.h" /* RVAL etc */
#include "LLlex.h"
#include "Lpars.h"
#include "stack.h"
#include "type.h"
#include "level.h"
#include "nofloat.h"
#include "l_state.h"
extern char *symbol2str();
extern struct type *func_type;
lint_conversion(oper, from_type, to_type)
struct type *from_type, *to_type;
{
register int from = from_type->tp_fund;
register int to = to_type->tp_fund;
switch (oper) {
case RETURN: /* not really an oper, but it works */
case INT2INT:
case '=':
case PLUSAB:
case MINAB:
case TIMESAB:
case DIVAB:
case MODAB:
case LEFTAB:
case RIGHTAB:
case ANDAB:
case XORAB:
case ORAB:
if ( (from == LONG && to != LONG)
|| (from == DOUBLE && to != DOUBLE)
) {
awarning("conversion from %s to %s may lose accuracy",
symbol2str(from), symbol2str(to));
}
}
}
lint_ret_conv(from_type)
struct type *from_type;
{
lint_conversion(RETURN, from_type, func_type);
}
lint_ptr_conv(from, to)
short from, to;
{
/* X -> X ok -- this includes struct -> struct, of any size
* X -> CHAR ok
* DOUBLE -> X ok
* FLOAT -> LONG -> INT -> SHORT ok
*/
if (from == to)
return;
if (to == CHAR)
return;
if (from == DOUBLE)
return;
switch (from) {
case FLOAT:
switch (to) {
case LONG:
case INT:
case SHORT:
return;
}
break;
case LONG:
switch (to) {
case INT:
case SHORT:
return;
}
break;
case INT:
switch (to) {
case SHORT:
return;
}
break;
}
if (from == CHAR) {
hwarning("pointer to char may not align correctly for a %s",
symbol2str(to));
}
else {
warning("pointer to %s may not align correctly for a %s",
symbol2str(from), symbol2str(to));
}
}
lint_relop(left, right, oper)
struct expr *left, *right;
int oper; /* '<', '>', LESSEQ, GREATEREQ, EQUAL, NOTEQUAL */
{
/* <unsigned> <relop> <neg-const|0> is doubtful */
if ( left->ex_type->tp_unsigned
&& right->ex_class == Value
&& right->VL_CLASS == Const
) {
if (right->VL_VALUE < 0) {
warning("unsigned compared to negative constant");
}
if (right->VL_VALUE == 0) {
switch (oper) {
case '<':
warning("unsigned < 0 will always fail");
break;
case LESSEQ:
warning("unsigned <= 0 is probably wrong");
break;
case GREATEREQ:
warning("unsigned >= 0 will always succeed");
break;
}
}
}
/* <char> <relop> <neg-const> is undefined */
if ( left->ex_type->tp_fund == CHAR
&& right->ex_class == Value
&& right->VL_CLASS == Const
&& (right->VL_VALUE < 0 || right->VL_VALUE > 127)
) {
warning("character compared to negative constant");
}
}
#endif LINT

414
lang/cem/cemcom/l_outdef.c Normal file
View file

@ -0,0 +1,414 @@
/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/* Lint outdef construction */
#include "lint.h"
#ifdef LINT
#include <alloc.h>
#include "arith.h"
#include "type.h"
#include "LLlex.h"
#include "Lpars.h"
#include "stack.h"
#include "def.h"
#include "struct.h"
#include "field.h"
#include "idf.h"
#include "level.h"
#include "label.h"
#include "expr.h"
#include "l_lint.h"
#include "l_outdef.h"
#include "l_class.h"
extern char *symbol2str();
extern int f_VARARGSn, LINTLIB;
int stat_number = 9999; /* static scope number */
struct outdef OutDef, OutCall;
lint_declare_idf(idf, sc)
struct idf *idf;
int sc;
{
register struct def *def = idf->id_def;
register int is_function = def->df_type->tp_fund == FUNCTION;
if (level == L_GLOBAL) {
lint_ext_def(idf, sc);
if (is_function)
def2decl(sc);
if (sc != TYPEDEF)
outdef();
}
else
if (level >= L_LOCAL && sc != STATIC && is_function) {
local_EFDC(idf);
}
}
lint_ext_def(idf, sc)
struct idf *idf;
{
/* At this place the following fields of the outputdefinition can be
* filled:
* name, stat_number, class, file, line, type.
* For variable definitions and declarations this will be all.
* For functions the fields nrargs and argtps are filled after parsing
* the arguments.
* The returns-field is known at the end of the function definition.
* sc indicates the storage class defined by the declaration specifier.
*/
register struct def *def = idf->id_def;
register struct type *type = def->df_type;
OutDef.od_name = idf->id_text;
OutDef.od_statnr = (sc == STATIC ? stat_number : 0);
switch (type->tp_fund) {
case ERRONEOUS:
OutDef.od_class = XXDF;
break;
case FUNCTION:
/* For the moment assume it will be a definition.
* If no compound_statement follows, it is a declaration,
* in which case the class will be adjusted by def2decl().
*/
OutDef.od_class = (sc == STATIC ? SFDF : EFDF);
break;
default: /* a variable */
OutDef.od_class =
sc == EXTERN ? EVDC :
sc == STATIC ? SVDF : EVDF;
break;
}
OutDef.od_file = def->df_file;
OutDef.od_line = def->df_line;
OutDef.od_type = (type->tp_fund == FUNCTION ? type->tp_up : type);
OutDef.od_valreturned = NORETURN;
}
def2decl(sc)
int sc;
{
/* It was assumed we were parsing a function definition.
* There was no compound statement following, so actually it was a
* declaration. This function updates the class.
*/
OutDef.od_class = (sc == STATIC ? XXDF : EFDC);
}
set_od_valreturned(n)
{
OutDef.od_valreturned = n;
}
local_EFDC(idf)
struct idf *idf;
{
struct outdef od;
od.od_class = EFDC;
od.od_statnr = 0;
od.od_name = idf->id_text;
od.od_file = idf->id_def->df_file;
od.od_line = idf->id_def->df_line;
od.od_type = idf->id_def->df_type->tp_up;
output_def(&od);
/* The other fields are not used for this class. */
}
lint_formals()
{
/* Make a list of tp_entries containing the types of the formal
* parameters of the function definition currently parsed.
*/
register struct stack_entry *se = stack_level_of(L_FORMAL1)->sl_entry;
register struct tp_entry **hook = &OutDef.od_entry;
OutDef.od_nrargs = 0;
while (se) {
register struct type *type = se->se_idf->id_def->df_type;
register struct tp_entry *te = new_tp_entry();
switch (type->tp_fund) {
/* Do the conversions on the formals that could not be
done in declare_idf().
It is, unfortunately, impossible not to do them,
since the corresponding actuals will have been
converted to generate proper code and we do not
want to duplicate the whole of expression handling
for lint.
*/
case CHAR:
case SHORT:
type = int_type;
break;
case FLOAT:
type = double_type;
break;
}
te->te_type = type;
te->te_class = !Const;
*hook = te;
hook = &te->next;
OutDef.od_nrargs++;
se = se->next;
}
if (f_VARARGSn > OutDef.od_nrargs) {
warning("VARARGS%d function has only %d arguments",
f_VARARGSn, OutDef.od_nrargs);
f_VARARGSn = OutDef.od_nrargs;
}
}
output_use(idf)
struct idf *idf;
{
/* Output the usage-definition of the variable described by idf.
*/
OutDef.od_name = idf->id_text;
OutDef.od_statnr = (idf->id_def->df_sc == STATIC ? stat_number : 0);
OutDef.od_class = VU;
OutDef.od_file = FileName;
OutDef.od_line = LineNumber;
OutDef.od_type = idf->id_def->df_type;
outdef();
}
outdef()
{
output_def(&OutDef);
}
outcall()
{
output_def(&OutCall);
}
output_def(od)
struct outdef *od;
{
/* As the types are output the tp_entries are removed, because they
* are then not needed anymore.
*/
if (od->od_class == XXDF)
return;
if (LINTLIB) {
switch (od->od_class) {
case EFDF:
od->od_class = LFDF;
break;
case EVDF:
od->od_class = LVDF;
break;
case SFDF:
/* remove tp_entries */
while (od->od_entry) {
register struct tp_entry *tmp = od->od_entry;
od->od_entry = od->od_entry->next;
free_tp_entry(tmp);
}
return;
default:
return;
}
}
printf("%s:%d:%c", od->od_name, od->od_statnr, od->od_class);
switch (od->od_class) {
case EFDF:
case SFDF:
case LFDF:
if (f_VARARGSn != -1) {
printf(":%d", -1 - f_VARARGSn);
outtypes(od->od_entry, f_VARARGSn);
}
else {
printf(":%d", od->od_nrargs);
outtypes(od->od_entry, od->od_nrargs);
}
od->od_entry = 0;
printf(":%d", od->od_valreturned);
break;
case FC:
printf(":%d", od->od_nrargs);
outtypes(od->od_entry, od->od_nrargs);
od->od_entry = 0;
printf(":%d", od->od_valused);
break;
case EVDF:
case SVDF:
case LVDF:
case EFDC:
case EVDC:
case IFDC:
case VU:
break;
default:
crash("(output_def) illegal class");
/*NOTREACHED*/
}
printf(":");
outtype(od->od_type);
printf(":%u:%s\n", od->od_line, od->od_file);
}
outtypes(te, n)
struct tp_entry *te;
{
/* Output n types in the tp_entry-list and remove all the entries */
register struct tp_entry *tmp;
while (n--) {
if (!te) {
crash("(outtypes) not enough tp_entries");
/*NOTREACHED*/
}
printf(":");
if (te->te_class == Const && te->te_value >= 0) {
/* constant non-negative actual parameter */
printf("+");
}
outtype(te->te_type);
if (te->te_type->tp_fund == FUNCTION) {
/* UGLY PATCH !!! ??? */
/* function names as operands are sometimes
FUNCTION and sometimes POINTER to FUNCTION,
depending on opaque circumstances. E.g., in
f(main, main);
the first main is PtF and the second is F.
*/
printf("*");
}
tmp = te;
te = te->next;
free_tp_entry(tmp);
}
/* remove the remaining entries */
while (te) {
tmp = te;
te = te->next;
free_tp_entry(tmp);
}
}
outtype(tp)
struct type *tp;
{
switch (tp->tp_fund) {
case POINTER:
outtype(tp->tp_up);
printf("*");
break;
case ARRAY:
outtype(tp->tp_up);
printf("*"); /* compatible with [] */
break;
case FUNCTION:
outtype(tp->tp_up);
printf("()");
break;
case STRUCT:
case UNION:
case ENUM:
printf("%s %s", symbol2str(tp->tp_fund), tp->tp_idf->id_text);
break;
case CHAR:
case INT:
case SHORT:
case LONG:
case FLOAT:
case DOUBLE:
case VOID:
case ERRONEOUS:
if (tp->tp_unsigned)
printf("unsigned ");
printf("%s", symbol2str(tp->tp_fund));
break;
default:
crash("(outtype) illegal tp_fund");
/*NOTREACHED*/
}
}
implicit_func_decl(idf, file, line)
struct idf *idf;
char *file;
unsigned int line;
{
struct outdef od;
od.od_class = IFDC;
od.od_statnr = 0;
od.od_name = idf->id_text;
od.od_file = file;
od.od_line = line;
od.od_type = idf->id_def->df_type->tp_up;
output_def(&od);
/* The other fields are not used for this class. */
}
fill_outcall(ex, used)
struct expr *ex;
int used;
{
register struct idf *idf = ex->OP_LEFT->VL_IDF;
register struct def *def = idf->id_def;
if (def->df_sc == IMPLICIT) {
implicit_func_decl(idf, ex->ex_file, ex->ex_line);
}
OutCall.od_type = def->df_type->tp_up;
OutCall.od_statnr = (def->df_sc == STATIC ? stat_number : 0);
OutCall.od_class = FC;
OutCall.od_name = idf->id_text;
OutCall.od_file = ex->ex_file;
OutCall.od_line = ex->ex_line;
OutCall.od_entry = (struct tp_entry *)0;
OutCall.od_nrargs = 0;
if ((ex = ex->OP_RIGHT) != 0) { /* function call with arguments */
/* store types of argument expressions in tp_entries */
while (ex->ex_class == Oper && ex->OP_OPER == PARCOMMA) {
fill_arg(ex->OP_RIGHT);
ex = ex->OP_LEFT;
}
fill_arg(ex);
}
OutCall.od_valused = used; /* USED, IGNORED or VOIDED */
}
fill_arg(e)
struct expr *e;
{
register struct tp_entry *te;
te = new_tp_entry();
te->te_type = e->ex_type;
if (is_cp_cst(e)) {
te->te_class = Const;
te->te_value = e->VL_VALUE;
}
else {
te->te_class = !Const;
te->te_value = (arith) 0;
}
te->next = OutCall.od_entry;
OutCall.od_entry = te;
OutCall.od_nrargs++;
}
#endif LINT

View file

@ -0,0 +1,31 @@
/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/* Lint output definition */
struct tp_entry {
struct tp_entry *next;
struct type *te_type;
int te_class; /* for constant parameters */
arith te_value;
};
/* ALLOCDEF "tp_entry" 10 */
struct outdef {
char od_class;
int od_statnr;
char *od_name;
char *od_file;
unsigned int od_line;
int od_nrargs;
struct tp_entry *od_entry; /* a list of the types of the
* formal parameters */
int od_valreturned;
/* NOVALRETURNED, VALRETURNED, NORETURN; see l_lint.h */
int od_valused;
/* USED, IGNORED, SET, VOIDED; see l_lint.h */
struct type *od_type;
};

View file

@ -0,0 +1,73 @@
/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/* Lint state stack */
/* These datastructures are used to implement a stack on which the
* state of automatic variables (including register variables) is
* kept.
* In this way it is possible to account for the flow of
* control of the program.
*/
struct switch_states {
struct state *sws_case;
struct state *sws_break;
int sws_default_met;
};
struct lint_stack_entry {
struct lint_stack_entry *next;
struct lint_stack_entry *ls_previous;
short ls_class; /* IF, WHILE, DO, FOR, SWITCH, CASE */
int ls_level;
struct state *ls_current; /* used by all classes */
union {
struct state *u_if_state; /* used for IF-class */
struct state *u_end; /* used for loop-classes */
struct switch_states u_switch;
} ls_states; /* not used for CASE-class */
};
/* macros to access the union */
#define LS_IF_STATE ls_states.u_if_state
#define LS_END ls_states.u_end
#define LS_CASE ls_states.u_switch.sws_case
#define LS_BREAK ls_states.u_switch.sws_break
#define LS_DEFAULT_MET ls_states.u_switch.sws_default_met
/* ALLOCDEF "lint_stack_entry" 10 */
struct state {
struct state *next; /* only used by memory allocator */
struct auto_def *st_auto_list;
int st_notreached; /* set if not reached */
int st_warned; /* set if warning issued */
};
/* ALLOCDEF "state" 15 */
struct auto_def {
struct auto_def *next;
struct idf *ad_idf;
struct def *ad_def;
int ad_used;
int ad_set;
int ad_maybe_set;
};
/* ALLOCDEF "auto_def" 20 */
struct expr_state {
struct expr_state *next;
struct idf *es_idf;
arith es_offset;
int es_used;
int es_set;
};
/* ALLOCDEF "expr_state" 20 */

1102
lang/cem/cemcom/l_states.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -5,6 +5,7 @@
/* $Header$ */
/* MAIN PROGRAM */
#include "lint.h"
#include "nofloat.h"
#include <system.h>
#include "nopp.h"
@ -95,6 +96,9 @@ main(argc, argv)
inc_max = 10;
init_pp(); /* initialise the preprocessor macros */
#ifdef LINT
lint_init();
#endif LINT
#endif NOPP
/* Note: source file "-" indicates that the source is supplied
@ -130,7 +134,10 @@ compile(argc, argv)
char *argv[];
{
char *result;
#ifndef LINT
register char *destination = 0;
#endif LINT
#ifdef DEBUG
#ifndef NOPP
int pp_only = options['E'] || options['P'] || options['C'];
@ -139,14 +146,17 @@ compile(argc, argv)
switch (argc) {
case 1:
#ifndef LINT
#ifdef DEBUG
#ifndef NOPP
if (!pp_only)
#endif NOPP
#endif
fatal("%s: destination file not specified", prog_name);
#endif LINT
break;
#ifndef LINT
case 2:
destination = argv[1];
break;
@ -154,8 +164,14 @@ compile(argc, argv)
nmlist = argv[2];
destination = argv[1];
break;
#endif LINT
default:
#ifndef LINT
fatal("use: %s source destination [namelist]", prog_name);
#else LINT
fatal("use: %s source", prog_name);
#endif LINT
break;
}
@ -185,8 +201,11 @@ compile(argc, argv)
#endif NOPP
#endif DEBUG
{
#ifndef LINT
init_code(destination && strcmp(destination, "-") != 0 ?
destination : 0);
#endif LINT
/* compile the source text */
C_program();

View file

@ -5,6 +5,7 @@
/* $Header$ */
/* U S E R O P T I O N - H A N D L I N G */
#include "lint.h"
#include "botch_free.h"
#include <alloc.h>
#include "nofloat.h"
@ -29,6 +30,10 @@ extern int inc_total;
#endif NOPP
char options[128]; /* one for every char */
#ifdef LINT
char loptions[128]; /* one for every char */
#endif LINT
extern int idfsize;
static int txt2int();
@ -45,13 +50,18 @@ next_option: /* to allow combined one-char options */
break;
default:
#ifndef LINT
fatal("illegal option: %c", opt);
#else LINT
warning("illegal option: %c", opt);
#endif LINT
break;
case '-':
options[*text++] = 1; /* flags, debug options etc. */
goto next_option;
#ifndef LINT
#ifdef DATAFLOW
case 'd':
#endif DATAFLOW
@ -59,16 +69,28 @@ next_option: /* to allow combined one-char options */
case 'L' : /* no fil/lin */
case 'n': /* use no registers */
case 'w': /* no warnings will be given */
#ifndef NOROPTION
case 'R': /* strict version */
#endif
options[opt] = 1;
goto next_option;
#ifdef NOROPTION
case 'R':
warning("-R option not implemented");
#endif LINT
#ifdef LINT
case 'h': /* heuristic tests */
case 'v': /* no complaints about unused arguments */
case 'a': /* check long->int int->long conversions */
case 'b': /* don't report unreachable break-statements */
case 'x': /* complain about unused extern declared variables */
case 'u': /* no "used but not defined"; for pass 2 */
loptions[opt] = 1;
goto next_option;
#endif LINT
case 'R': /* strict version */
#ifndef NOROPTION
options[opt] = 1;
#else NOROPTION
warning("-R option not implemented");
#endif NOROPTION
goto next_option;
#endif
#ifdef ___XXX___
deleted, is now a debug-flag
@ -180,6 +202,14 @@ deleted, is now a debug-flag
break;
#endif ___XXX___
#ifdef LINT
case 'S' : { /* -Sint : static scope number for lint */
extern int stat_number;
stat_number = txt2int(&text);
break;
}
#endif LINT
case 'T' : {
#ifdef USE_TMP
extern char *C_tmpdir;
@ -209,6 +239,7 @@ deleted, is now a debug-flag
break;
}
#ifndef LINT
case 'V' : /* set object sizes and alignment requirements */
#ifdef NOCROSS
warning("-V option ignored");
@ -294,6 +325,7 @@ deleted, is now a debug-flag
break;
}
#endif NOCROSS
#endif LINT
}
}

View file

@ -45,6 +45,7 @@
%start If_expr, control_if_expression;
{
#include "lint.h"
#include "nopp.h"
#include "arith.h"
#include "LLlex.h"
@ -56,6 +57,10 @@
#include "code.h"
#include "expr.h"
#include "def.h"
#ifdef LINT
#include "l_state.h"
#endif LINT
#ifndef NOPP
extern arith ifval;
#endif NOPP
@ -121,6 +126,9 @@ external_definition
declarator(&Dc)
{
declare_idf(&Ds, &Dc, level);
#ifdef LINT
lint_ext_def(Dc.dc_idf, Ds.ds_sc);
#endif LINT
}
[%if (Dc.dc_idf->id_def->df_type->tp_fund == FUNCTION)
/* int i (1) {2, 3}
@ -156,6 +164,12 @@ non_function(register struct decspecs *ds; register struct declarator *dc;)
{ code_declaration(dc->dc_idf, (struct expr *) 0, level, ds->ds_sc); }
]
{
#ifdef LINT
if (dc->dc_idf->id_def->df_type->tp_fund == FUNCTION)
def2decl(ds->ds_sc);
if (dc->dc_idf->id_def->df_sc != TYPEDEF)
outdef();
#endif LINT
}
[
','
@ -171,6 +185,9 @@ function(struct decspecs *ds; struct declarator *dc;)
}
:
{ register struct idf *idf = dc->dc_idf;
#ifdef LINT
lint_start_function();
#endif LINT
init_idf(idf);
stack_level(); /* L_FORMAL1 declarations */
declare_params(dc);
@ -180,11 +197,23 @@ function(struct decspecs *ds; struct declarator *dc;)
declaration*
{
declare_formals(&fbytes);
#ifdef LINT
lint_formals();
#endif LINT
}
compound_statement
{
end_proc(fbytes);
#ifdef LINT
lint_return_stmt(0); /* implicit return at end of function */
#endif LINT
unstack_level(); /* L_FORMAL2 declarations */
#ifdef LINT
check_args_used();
#endif LINT
unstack_level(); /* L_FORMAL1 declarations */
#ifdef LINT
lint_end_function();
#endif LINT
}
;

View file

@ -5,6 +5,7 @@
/* $Header$ */
/* S T A C K / U N S T A C K R O U T I N E S */
#include "lint.h"
#include "nofloat.h"
#include <system.h>
#include <em.h>
@ -51,6 +52,9 @@ stack_level() {
stl->sl_level = ++level;
stl->sl_max_block = loclev->sl_max_block;
local_level = stl;
#ifdef LINT
lint_start_local();
#endif LINT
}
stack_idf(idf, stl)
@ -96,6 +100,10 @@ unstack_level()
dumpidftab("before unstackidfs", 0);
#endif DEBUG
#ifdef LINT
lint_local_level(local_level);
#endif LINT
/* The implementation below is more careful than strictly
necessary. Optimists may optimize it afterwards.
*/
@ -168,6 +176,10 @@ unstack_world()
*/
register struct stack_entry *se = local_level->sl_entry;
#ifdef LINT
lint_global_level(local_level);
#endif LINT
open_name_list();
while (se) {

View file

@ -8,6 +8,7 @@
{
#include <em.h>
#include "lint.h"
#include "debug.h"
#include "botch_free.h"
@ -20,6 +21,11 @@
#include "code.h"
#include "stack.h"
#include "def.h"
#ifdef LINT
#include "l_lint.h"
#include "l_state.h"
#endif LINT
extern int level;
}
@ -31,6 +37,9 @@ extern int level;
/* 9 */
statement
{
#ifdef LINT
lint_statement();
#endif LINT
}
:
%if (AHEAD != ':')
@ -57,12 +66,18 @@ statement
BREAK
{
code_break();
#ifdef LINT
lint_break_stmt();
#endif LINT
}
';'
|
CONTINUE
{
code_continue();
#ifdef LINT
lint_continue_stmt();
#endif LINT
}
';'
|
@ -104,6 +119,9 @@ label
grz: printf("A labelled statement\n");
}
*/
#ifdef LINT
lint_label();
#endif LINT
define_label(idf);
C_df_ilb((label)idf->id_def->df_address);
}
@ -126,6 +144,9 @@ if_statement
/* The comparison has been optimized
to a 0 or 1.
*/
#ifdef LINT
hwarning("condition in if is constant");
#endif LINT
if (expr->VL_VALUE == (arith)0) {
C_bra(l_false);
}
@ -136,21 +157,33 @@ if_statement
C_df_ilb(l_true);
}
free_expression(expr);
#ifdef LINT
start_if_part();
#endif LINT
}
')'
statement
[%prefer
ELSE
{
#ifdef LINT
start_else_part();
#endif LINT
C_bra(l_end);
C_df_ilb(l_false);
}
statement
{ C_df_ilb(l_end);
#ifdef LINT
end_if_else_stmt();
#endif LINT
}
|
empty
{ C_df_ilb(l_false);
#ifdef LINT
end_if_stmt();
#endif LINT
}
]
;
@ -176,10 +209,17 @@ while_statement
if (expr->VL_VALUE == (arith)0) {
C_bra(l_break);
}
#ifdef LINT
start_loop_stmt(WHILE, 1,
expr->VL_VALUE != (arith)0);
#endif LINT
}
else {
code_expr(expr, RVAL, TRUE, l_body, l_break);
C_df_ilb(l_body);
#ifdef LINT
start_loop_stmt(WHILE, 0, 0);
#endif LINT
}
}
')'
@ -189,6 +229,9 @@ while_statement
C_df_ilb(l_break);
unstack_stmt();
free_expression(expr);
#ifdef LINT
end_loop_stmt();
#endif LINT
}
;
@ -202,6 +245,9 @@ do_statement
DO
{ C_df_ilb(l_body);
stack_stmt(l_break, l_continue);
#ifdef LINT
start_loop_stmt(DO, 1, 1);
#endif LINT
}
statement
WHILE
@ -215,9 +261,15 @@ do_statement
if (expr->VL_VALUE == (arith)1) {
C_bra(l_body);
}
#ifdef LINT
end_do_stmt(1, expr->VL_VALUE != (arith)0);
#endif LINT
}
else {
code_expr(expr, RVAL, TRUE, l_body, l_break);
#ifdef LINT
end_do_stmt(0, 0);
#endif LINT
}
C_df_ilb(l_break);
}
@ -235,6 +287,9 @@ for_statement
label l_continue = text_label();
label l_body = text_label();
label l_test = text_label();
#ifdef LINT
int const = 1, cond = 1; /* the default case */
#endif LINT
}
:
FOR
@ -257,10 +312,17 @@ for_statement
if (e_test->VL_VALUE == (arith)0) {
C_bra(l_break);
}
#ifdef LINT
const = 1,
cond = e_test->VL_VALUE != (arith)0;
#endif LINT
}
else {
code_expr(e_test, RVAL, TRUE, l_body, l_break);
C_df_ilb(l_body);
#ifdef LINT
const = 0, cond = 0;
#endif LINT
}
}
]?
@ -268,9 +330,15 @@ for_statement
expression(&e_incr)?
')'
{
#ifdef LINT
start_loop_stmt(FOR, const, cond);
#endif LINT
}
statement
{
#ifdef LINT
end_loop_stmt();
#endif LINT
C_df_ilb(l_continue);
if (e_incr)
code_expr(e_incr, RVAL, FALSE,
@ -294,10 +362,22 @@ switch_statement
expression(&expr)
{
code_startswitch(&expr);
#ifdef LINT
start_switch_part();
/* the following is a trick to detect a constant
* expression in a switch
*/
opnd2test(&expr, SWITCH);
if (is_cp_cst(expr))
hwarning("switch value is constant");
#endif LINT
}
')'
statement
{
#ifdef LINT
end_switch_stmt();
#endif LINT
code_endswitch();
free_expression(expr);
}
@ -311,6 +391,9 @@ case_statement
CASE
constant_expression(&expr)
{
#ifdef LINT
lint_case_stmt(0);
#endif LINT
code_case(expr);
free_expression(expr);
}
@ -322,6 +405,9 @@ default_statement
:
DEFAULT
{
#ifdef LINT
lint_case_stmt(1);
#endif LINT
code_default();
}
':'
@ -336,13 +422,23 @@ return_statement
[
expression(&expr)
{
#ifdef LINT
lint_ret_conv(expr->ex_type);
#endif LINT
do_return_expr(expr);
free_expression(expr);
#ifdef LINT
lint_return_stmt(1);
#endif LINT
}
|
empty
{
do_return();
#ifdef LINT
lint_return_stmt(0);
#endif LINT
}
]
';'
@ -358,6 +454,9 @@ jump
{
apply_label(idf);
C_bra((label)idf->id_def->df_address);
#ifdef LINT
lint_jump_stmt(idf);
#endif LINT
}
;

View file

@ -16,6 +16,7 @@
#include <alloc.h>
#include <em_mes.h>
#include "lint.h"
#include "util.h"
#include "use_tmp.h"
#include "regcount.h"
@ -224,6 +225,7 @@ StoreLocal(off, sz)
}
}
#ifndef LINT
AddrLocal(off)
arith off;
{
@ -232,3 +234,4 @@ AddrLocal(off)
if (p) p->t_regtype = -1;
C_lal(off);
}
#endif LINT