some leaks plugged (as detected by the leak detector)

This commit is contained in:
dick 1986-07-18 21:10:42 +00:00
parent c9a188825d
commit 824293a681
21 changed files with 204 additions and 176 deletions

View file

@ -56,7 +56,7 @@ GOBJ = char.o symbol2str.o next.o
# generated source files # generated source files
GSRC = char.c symbol2str.c next.c \ GSRC = char.c symbol2str.c next.c \
code.h declar.h decspecs.h def.h expr.h field.h \ code.h declar.h decspecs.h def.h expr.h field.h \
idf.h macro.h stack.h struct.h switch.h type.h idf.h macro.h stack.h stmt.h struct.h switch.h type.h
# .h files generated by `make hfiles'; PLEASE KEEP THIS UP-TO-DATE! # .h files generated by `make hfiles'; PLEASE KEEP THIS UP-TO-DATE!
GHSRC = botch_free.h dataflow.h debug.h density.h errout.h \ GHSRC = botch_free.h dataflow.h debug.h density.h errout.h \
@ -71,7 +71,7 @@ GENERATED = tab tokenfile.g Lpars.h LLfiles LL.output lint.out \
# include files containing ALLOCDEF specifications # include files containing ALLOCDEF specifications
NEXTFILES = code.str declar.str decspecs.str def.str expr.str field.str \ NEXTFILES = code.str declar.str decspecs.str def.str expr.str field.str \
idf.str macro.str stack.str struct.str switch.str type.str idf.str macro.str stack.str stmt.str struct.str switch.str type.str
.SUFFIXES: .str .h .SUFFIXES: .str .h
.str.h: .str.h:
@ -90,7 +90,7 @@ cem: cem.c
lint.cem: cem.c lint.cem: cem.c
lint -abx cem.c lint -abx cem.c
hfiles: Parameters hfiles: ./make.hfiles Parameters
./make.hfiles Parameters ./make.hfiles Parameters
@touch hfiles @touch hfiles
@ -119,6 +119,7 @@ field.h: make.allocd
idf.h: make.allocd idf.h: make.allocd
macro.h: make.allocd macro.h: make.allocd
stack.h: make.allocd stack.h: make.allocd
stmt.h: make.allocd
struct.h: make.allocd struct.h: make.allocd
switch.h: make.allocd switch.h: make.allocd
type.h: make.allocd type.h: make.allocd
@ -202,7 +203,7 @@ ch7bin.o: Lpars.h arith.h botch_free.h expr.h idf.h label.h nobitfield.h nopp.h
cstoper.o: Lpars.h arith.h assert.h debug.h expr.h idf.h label.h nobitfield.h nopp.h sizes.h spec_arith.h target_sizes.h type.h cstoper.o: Lpars.h arith.h assert.h debug.h expr.h idf.h label.h nobitfield.h nopp.h sizes.h spec_arith.h target_sizes.h type.h
arith.o: Lpars.h alloc.h arith.h botch_free.h expr.h field.h idf.h label.h mes.h nobitfield.h nopp.h spec_arith.h storage.h type.h arith.o: Lpars.h alloc.h arith.h botch_free.h expr.h field.h idf.h label.h mes.h nobitfield.h nopp.h spec_arith.h storage.h type.h
alloc.o: alloc.h assert.h debug.h myalloc.h alloc.o: alloc.h assert.h debug.h myalloc.h
code.o: LLlex.h Lpars.h alloc.h arith.h assert.h atw.h botch_free.h code.h dataflow.h debug.h declar.h decspecs.h def.h expr.h idf.h label.h level.h mes.h nobitfield.h nopp.h sizes.h spec_arith.h specials.h stack.h storage.h type.h use_tmp.h code.o: LLlex.h Lpars.h alloc.h arith.h assert.h atw.h botch_free.h code.h dataflow.h debug.h declar.h decspecs.h def.h expr.h idf.h label.h level.h mes.h nobitfield.h nopp.h sizes.h spec_arith.h specials.h stack.h stmt.h storage.h type.h use_tmp.h
dumpidf.o: Lpars.h arith.h debug.h def.h expr.h field.h idf.h label.h nobitfield.h nopp.h spec_arith.h stack.h struct.h type.h dumpidf.o: Lpars.h arith.h debug.h def.h expr.h field.h idf.h label.h nobitfield.h nopp.h spec_arith.h stack.h struct.h type.h
error.o: LLlex.h arith.h debug.h errout.h expr.h label.h nopp.h spec_arith.h tokenname.h use_tmp.h error.o: LLlex.h arith.h debug.h errout.h expr.h label.h nopp.h spec_arith.h tokenname.h use_tmp.h
field.o: Lpars.h arith.h assert.h code.h debug.h expr.h field.h idf.h label.h nobitfield.h nopp.h sizes.h spec_arith.h type.h field.o: Lpars.h arith.h assert.h code.h debug.h expr.h field.h idf.h label.h nobitfield.h nopp.h sizes.h spec_arith.h type.h
@ -217,7 +218,7 @@ options.o: align.h arith.h class.h idf.h idfsize.h macro.h maxincl.h nobitfield.
scan.o: class.h idf.h input.h interface.h lapbuf.h macro.h nopp.h nparams.h scan.o: class.h idf.h input.h interface.h lapbuf.h macro.h nopp.h nparams.h
skip.o: LLlex.h arith.h class.h input.h interface.h nopp.h spec_arith.h skip.o: LLlex.h arith.h class.h input.h interface.h nopp.h spec_arith.h
stack.o: Lpars.h alloc.h arith.h botch_free.h debug.h def.h idf.h level.h mes.h nobitfield.h nopp.h spec_arith.h stack.h storage.h struct.h type.h use_tmp.h stack.o: Lpars.h alloc.h arith.h botch_free.h debug.h def.h idf.h level.h mes.h nobitfield.h nopp.h spec_arith.h stack.h storage.h struct.h type.h use_tmp.h
type.o: Lpars.h align.h alloc.h arith.h def.h idf.h nobitfield.h nopp.h sizes.h spec_arith.h type.h type.o: Lpars.h align.h alloc.h arith.h def.h idf.h nobitfield.h nopp.h sizes.h spec_arith.h storage.h type.h
ch7mon.o: Lpars.h arith.h botch_free.h def.h expr.h idf.h label.h nobitfield.h nopp.h spec_arith.h storage.h type.h ch7mon.o: Lpars.h arith.h botch_free.h def.h expr.h idf.h label.h nobitfield.h nopp.h spec_arith.h storage.h type.h
label.o: Lpars.h arith.h def.h idf.h label.h level.h nobitfield.h nopp.h spec_arith.h type.h label.o: Lpars.h arith.h def.h idf.h label.h level.h nobitfield.h nopp.h spec_arith.h type.h
eval.o: Lpars.h align.h arith.h assert.h atw.h code.h dataflow.h debug.h def.h expr.h idf.h label.h level.h mes.h nobitfield.h nopp.h sizes.h spec_arith.h stack.h type.h eval.o: Lpars.h align.h arith.h assert.h atw.h code.h dataflow.h debug.h def.h expr.h idf.h label.h level.h mes.h nobitfield.h nopp.h sizes.h spec_arith.h stack.h type.h
@ -228,7 +229,7 @@ conversion.o: Lpars.h arith.h nobitfield.h sizes.h spec_arith.h type.h
blocks.o: arith.h atw.h sizes.h spec_arith.h blocks.o: arith.h atw.h sizes.h spec_arith.h
dataflow.o: dataflow.h dataflow.o: dataflow.h
tokenfile.o: Lpars.h tokenfile.o: Lpars.h
declar.o: LLlex.h Lpars.h arith.h debug.h declar.h decspecs.h def.h expr.h field.h idf.h label.h nobitfield.h nopp.h sizes.h spec_arith.h struct.h type.h declar.o: LLlex.h Lpars.h arith.h debug.h declar.h decspecs.h def.h expr.h field.h idf.h label.h nobitfield.h nopp.h sizes.h spec_arith.h storage.h struct.h type.h
statement.o: LLlex.h Lpars.h arith.h botch_free.h code.h debug.h def.h expr.h idf.h label.h nobitfield.h nopp.h spec_arith.h stack.h storage.h type.h statement.o: LLlex.h Lpars.h arith.h botch_free.h code.h debug.h def.h expr.h idf.h label.h nobitfield.h nopp.h spec_arith.h stack.h storage.h type.h
expression.o: LLlex.h Lpars.h arith.h expr.h idf.h label.h nobitfield.h nopp.h spec_arith.h type.h expression.o: LLlex.h Lpars.h arith.h expr.h idf.h label.h nobitfield.h nopp.h spec_arith.h type.h
program.o: LLlex.h Lpars.h alloc.h arith.h code.h declar.h decspecs.h def.h expr.h idf.h label.h nobitfield.h nopp.h spec_arith.h type.h program.o: LLlex.h Lpars.h alloc.h arith.h code.h declar.h decspecs.h def.h expr.h idf.h label.h nobitfield.h nopp.h spec_arith.h type.h

View file

@ -1,5 +1,5 @@
!File: myalloc.h !File: myalloc.h
#define OWNALLOC 1 /* use own superfast allocation */ #define OWNALLOC 1 /* use own superfast allocation */
#define ALLOCSIZ 4096 /* allocate pieces of 4K */ #define ALLOCSIZ 4096 /* allocate pieces of 4K */
#define ALIGNSIZE 8 /* needed for alloc.c */ #define ALIGNSIZE 8 /* needed for alloc.c */

View file

@ -12,6 +12,7 @@
#include "idf.h" #include "idf.h"
#include "label.h" #include "label.h"
#include "code.h" #include "code.h"
#include "stmt.h"
#include "alloc.h" #include "alloc.h"
#include "def.h" #include "def.h"
#include "expr.h" #include "expr.h"
@ -28,7 +29,7 @@
#include "atw.h" #include "atw.h"
#include "assert.h" #include "assert.h"
static struct stat_block *stat_sp, *stat_head; static struct stmt_block *stmt_stack;
char *symbol2str(); char *symbol2str();
int fp_used; int fp_used;
@ -37,20 +38,18 @@ label datlab_count = 1;
extern char options[]; extern char options[];
/* init_code() initialises the output file on which the compact
EM code is written
*/
init_code(dst_file) init_code(dst_file)
char *dst_file; char *dst_file;
{ {
/* init_code() initialises the output file on which the
compact EM code is written
*/
C_init(word_size, pointer_size); /* initialise EM module */ C_init(word_size, pointer_size); /* initialise EM module */
if (C_open(dst_file) == 0) if (C_open(dst_file) == 0)
fatal("cannot write to %s\n", dst_file); fatal("cannot write to %s\n", dst_file);
#ifndef USE_TMP #ifndef USE_TMP
famous_first_words(); famous_first_words();
#endif USE_TMP #endif USE_TMP
stat_sp = stat_head = new_stat_block();
clear((char *)stat_sp, sizeof(struct stat_block));
} }
famous_first_words() famous_first_words()
@ -162,18 +161,18 @@ static label func_res_label;
static char *last_fn_given = ""; static char *last_fn_given = "";
static label file_name_label; static label file_name_label;
/* begin_proc() is called at the entrance of a new function
and performs the necessary code generation:
- a scope indicator (if needed) exp/inp
- the procedure entry pro $name
- reserves some space if the result of the function
does not fit in the return area
- a fil pseudo instruction
*/
begin_proc(name, def) /* to be called when entering a procedure */ begin_proc(name, def) /* to be called when entering a procedure */
char *name; char *name;
struct def *def; struct def *def;
{ {
/* begin_proc() is called at the entrance of a new function
and performs the necessary code generation:
- a scope indicator (if needed) exp/inp
- the procedure entry pro $name
- reserves some space if the result of the function
does not fit in the return area
- a fil pseudo instruction
*/
arith size; arith size;
#ifndef USE_TMP #ifndef USE_TMP
@ -217,20 +216,21 @@ begin_proc(name, def) /* to be called when entering a procedure */
} }
} }
/* end_proc() deals with the code to be generated at the end of
a function, as there is:
- the EM ret instruction: "ret 0"
- loading of the function result in the function result area
if there has been a return <expr> in the function body
(see do_return_expr())
- indication of the use of floating points
- indication of the number of bytes used for formal parameters
- use of special identifiers such as "setjmp"
- "end" + number of bytes used for local variables
*/
end_proc(fbytes, nbytes) end_proc(fbytes, nbytes)
arith fbytes, nbytes; arith fbytes, nbytes;
{ {
/* end_proc() deals with the code to be generated at the end of
a function, as there is:
- the EM ret instruction: "ret 0"
- loading of the function result in the function
result area if there has been a return <expr>
in the function body (see do_return_expr())
- indication of the use of floating points
- indication of the number of bytes used for
formal parameters
- use of special identifiers such as "setjmp"
- "end" + number of bytes used for local variables
*/
static int mes_flt_given = 0; /* once for the whole program */ static int mes_flt_given = 0; /* once for the whole program */
#ifdef DATAFLOW #ifdef DATAFLOW
@ -296,6 +296,10 @@ code_declaration(idf, expr, lvl, sc)
- global variables, coded only if initialized; - global variables, coded only if initialized;
- local static variables; - local static variables;
- local automatic variables; - local automatic variables;
Since the expression may be modified in the process,
code_declaration() frees it after use, as the caller can
no longer do so.
If there is a storage class indication (EXTERN/STATIC), If there is a storage class indication (EXTERN/STATIC),
code_declaration() will generate an exa or ina. code_declaration() will generate an exa or ina.
The sc is the actual storage class, as given in the The sc is the actual storage class, as given in the
@ -328,6 +332,7 @@ code_declaration(idf, expr, lvl, sc)
def->df_alloc = ALLOC_DONE; def->df_alloc = ALLOC_DONE;
C_df_dnam(text); C_df_dnam(text);
do_ival(&(def->df_type), expr); do_ival(&(def->df_type), expr);
free_expression(expr);
} }
} }
else else
@ -341,8 +346,11 @@ code_declaration(idf, expr, lvl, sc)
integer label in EM. integer label in EM.
*/ */
C_df_dlb((label)def->df_address); C_df_dlb((label)def->df_address);
if (expr) /* there is an initialisation */ if (expr) {
/* there is an initialisation */
do_ival(&(def->df_type), expr); do_ival(&(def->df_type), expr);
free_expression(expr);
}
else { /* produce blank space */ else { /* produce blank space */
if (size <= 0) { if (size <= 0) {
error("size of %s unknown", text); error("size of %s unknown", text);
@ -378,6 +386,7 @@ loc_init(expr, id)
{ {
/* loc_init() generates code for the assignment of /* loc_init() generates code for the assignment of
expression expr to the local variable described by id. expression expr to the local variable described by id.
It frees the expression afterwards.
*/ */
register struct type *tp = id->id_def->df_type; register struct type *tp = id->id_def->df_type;
@ -388,6 +397,7 @@ loc_init(expr, id)
case STRUCT: case STRUCT:
case UNION: case UNION:
error("no automatic aggregate initialisation"); error("no automatic aggregate initialisation");
free_expression(expr);
return; return;
} }
@ -407,8 +417,9 @@ loc_init(expr, id)
else { /* not embraced */ else { /* not embraced */
struct value vl; struct value vl;
ch7cast(&expr, '=', tp); ch7cast(&expr, '=', tp); /* may modify expr */
EVAL(expr, RVAL, TRUE, NO_LABEL, NO_LABEL); EVAL(expr, RVAL, TRUE, NO_LABEL, NO_LABEL);
free_expression(expr);
vl.vl_class = Name; vl.vl_class = Name;
vl.vl_data.vl_idf = id; vl.vl_data.vl_idf = id;
vl.vl_value = (arith)0; vl.vl_value = (arith)0;
@ -416,11 +427,11 @@ loc_init(expr, id)
} }
} }
/* bss() allocates bss space for the global idf.
*/
bss(idf) bss(idf)
struct idf *idf; struct idf *idf;
{ {
/* bss() allocates bss space for the global idf.
*/
register struct def *def = idf->id_def; register struct def *def = idf->id_def;
arith size = def->df_type->tp_size; arith size = def->df_type->tp_size;
@ -454,85 +465,80 @@ formal_cvt(def)
} }
} }
/* code_expr() is the parser's interface to the expression code
generator.
If line number trace is wanted, it generates a lin instruction.
EVAL() is called directly.
*/
code_expr(expr, val, code, tlbl, flbl) code_expr(expr, val, code, tlbl, flbl)
struct expr *expr; struct expr *expr;
label tlbl, flbl; label tlbl, flbl;
{ {
/* code_expr() is the parser's interface to the expression code
generator.
If line number trace is wanted, it generates a
lin instruction. EVAL() is called directly.
*/
if (options['p']) /* profiling */ if (options['p']) /* profiling */
C_lin((arith)LineNumber); C_lin((arith)LineNumber);
EVAL(expr, val, code, tlbl, flbl); EVAL(expr, val, code, tlbl, flbl);
} }
/* The FOR/WHILE/DO/SWITCH stacking mechanism: /* The FOR/WHILE/DO/SWITCH stacking mechanism:
stat_stack() has to be called at the entrance of a stack_stmt() has to be called at the entrance of a
for, while, do or switch statement to indicate the for, while, do or switch statement to indicate the
EM labels where a subsequent break or continue causes EM labels where a subsequent break or continue causes
the program to jump to. the program to jump to.
*/ */
/* do_break() generates EM code needed at the occurrence of "break": /* code_break() generates EM code needed at the occurrence of "break":
it generates a branch instruction to the break label of the it generates a branch instruction to the break label of the
innermost statement in which break has a meaning. innermost statement in which break has a meaning.
As "break" is legal in any of 'while', 'do', 'for' or 'switch', As "break" is legal in any of 'while', 'do', 'for' or 'switch',
which are the only ones that are stacked, only the top of which are the only ones that are stacked, only the top of
the stack is interesting. the stack is interesting.
0 is returned if the break cannot be bound to any enclosing
statement.
*/ */
int code_break()
do_break()
{ {
register struct stat_block *stat_ptr = stat_sp; register struct stmt_block *stmt_block = stmt_stack;
if (stat_ptr) { if (stmt_block) {
C_bra(stat_ptr->st_break); C_bra(stmt_block->st_break);
return 1; return;
} }
return 0; /* break is illegal */ error("break not inside for, while, do or switch");
} }
/* do_continue() generates EM code needed at the occurrence of "continue": /* code_continue() generates EM code needed at the occurrence of
"continue":
it generates a branch instruction to the continue label of the it generates a branch instruction to the continue label of the
innermost statement in which continue has a meaning. innermost statement in which continue has a meaning.
0 is returned if the continue cannot be bound to any enclosing
statement.
*/ */
int code_continue()
do_continue()
{ {
register struct stat_block *stat_ptr = stat_sp; register struct stmt_block *stmt_block = stmt_stack;
while (stat_ptr) { while (stmt_block) {
if (stat_ptr->st_continue) { if (stmt_block->st_continue) {
C_bra(stat_ptr->st_continue); C_bra(stmt_block->st_continue);
return 1; return;
} }
stat_ptr = stat_ptr->next; stmt_block = stmt_block->next;
} }
return 0; error("continue not inside for, while or do");
} }
stat_stack(break_label, cont_label) stack_stmt(break_label, cont_label)
label break_label, cont_label; label break_label, cont_label;
{ {
register struct stat_block *newb = new_stat_block(); register struct stmt_block *stmt_block = new_stmt_block();
newb->next = stat_sp; stmt_block->next = stmt_stack;
newb->st_break = break_label; stmt_block->st_break = break_label;
newb->st_continue = cont_label; stmt_block->st_continue = cont_label;
stat_sp = newb; stmt_stack = stmt_block;
} }
/* stat_unstack() unstacks the data of a statement unstack_stmt()
which may contain break or continue
*/
stat_unstack()
{ {
register struct stat_block *sbp = stat_sp; /* unstack_stmt() unstacks the data of a statement
stat_sp = stat_sp->next; which may contain break or continue
free_stat_block(sbp); */
register struct stmt_block *sbp = stmt_stack;
stmt_stack = stmt_stack->next;
free_stmt_block(sbp);
} }

View file

@ -1,14 +1,6 @@
/* $Header$ */ /* $Header$ */
/* C O D E - G E N E R A T O R D E F I N I T I O N S */ /* C O D E - G E N E R A T O R D E F I N I T I O N S */
struct stat_block {
struct stat_block *next;
label st_break;
label st_continue;
};
/* ALLOCDEF "stat_block" */
struct string_cst { /* storing string constants */ struct string_cst { /* storing string constants */
struct string_cst *next; struct string_cst *next;
char *sc_value; char *sc_value;

View file

@ -180,6 +180,7 @@ cstbin(expp, oper, expr)
cut_size(*expp); cut_size(*expp);
(*expp)->ex_flags |= expr->ex_flags; (*expp)->ex_flags |= expr->ex_flags;
(*expp)->ex_flags &= ~EX_PARENS; (*expp)->ex_flags &= ~EX_PARENS;
free_expression(expr);
} }
cut_size(expr) cut_size(expr)

View file

@ -16,6 +16,7 @@
#include "label.h" #include "label.h"
#include "expr.h" #include "expr.h"
#include "sizes.h" #include "sizes.h"
#include "storage.h"
extern char options[]; extern char options[];
} }
@ -151,7 +152,6 @@ init_declarator(struct decspecs *ds;)
initializer(Dc.dc_idf, &expr)? initializer(Dc.dc_idf, &expr)?
{ {
code_declaration(Dc.dc_idf, expr, level, ds->ds_sc); code_declaration(Dc.dc_idf, expr, level, ds->ds_sc);
free_expression(expr);
} }
] ]
{remove_declarator(&Dc);} {remove_declarator(&Dc);}
@ -167,7 +167,7 @@ init_declarator(struct decspecs *ds;)
declarator(struct declarator *dc;) declarator(struct declarator *dc;)
{ {
arith count; arith count;
struct idstack_item *is = 0; struct formal *fm = 0;
} }
: :
[ [
@ -177,11 +177,11 @@ declarator(struct declarator *dc;)
old-fashioned initialization. old-fashioned initialization.
*/ */
'(' '('
formal_list(&is) ? /* semantic check later... */ formal_list(&fm) ? /* semantic check later... */
')' ')'
{ {
add_decl_unary(dc, FUNCTION, (arith)0, is); add_decl_unary(dc, FUNCTION, (arith)0, fm);
is = 0; fm = 0;
} }
| |
arrayer(&count) arrayer(&count)
@ -219,21 +219,21 @@ arrayer(arith *sizep;)
']' ']'
; ;
formal_list (struct idstack_item **is;) formal_list (struct formal **fmp;)
: :
formal(is) [ ',' formal(is) ]* formal(fmp) [ ',' formal(fmp) ]*
; ;
formal(struct idstack_item **is;) formal(struct formal **fmp;)
{struct idf *idf; } {struct idf *idf; }
: :
identifier(&idf) identifier(&idf)
{ {
struct idstack_item *new = new_idstack_item(); struct formal *new = new_formal();
new->is_idf = idf; new->fm_idf = idf;
new->next = *is; new->next = *fmp;
*is = new; *fmp = new;
} }
; ;

View file

@ -10,12 +10,20 @@ struct declarator {
struct declarator *next; struct declarator *next;
struct idf *dc_idf; struct idf *dc_idf;
struct decl_unary *dc_decl_unary; struct decl_unary *dc_decl_unary;
struct idstack_item *dc_fparams; /* params for function */ struct formal *dc_formal; /* params for function */
}; };
/* ALLOCDEF "declarator" */ /* ALLOCDEF "declarator" */
#define NO_PARAMS ((struct idstack_item *) 0)
struct formal { /* list of formals */
struct formal *next;
struct idf *fm_idf;
};
/* ALLOCDEF "formal" */
#define NO_PARAMS ((struct formal *) 0)
struct decl_unary { struct decl_unary {
struct decl_unary *next; struct decl_unary *next;

View file

@ -32,10 +32,10 @@ declare_type(tp, dc)
return tp; return tp;
} }
add_decl_unary(dc, fund, count, is) add_decl_unary(dc, fund, count, fm)
struct declarator *dc; struct declarator *dc;
arith count; arith count;
struct idstack_item *is; struct formal *fm;
{ {
/* A decl_unary describing a constructor with fundamental /* A decl_unary describing a constructor with fundamental
type fund and with size count is inserted in front of the type fund and with size count is inserted in front of the
@ -47,14 +47,14 @@ add_decl_unary(dc, fund, count, is)
new->next = dc->dc_decl_unary; new->next = dc->dc_decl_unary;
new->du_fund = fund; new->du_fund = fund;
new->du_count = count; new->du_count = count;
if (is) { if (fm) {
if (dc->dc_decl_unary) { if (dc->dc_decl_unary) {
/* paramlist only allowed at first decl_unary */ /* paramlist only allowed at first decl_unary */
error("formal parameter list discarded"); error("formal parameter list discarded");
} }
else { else {
/* register the parameters */ /* register the parameters */
dc->dc_fparams = is; dc->dc_formal = fm;
} }
} }
dc->dc_decl_unary = new; dc->dc_decl_unary = new;
@ -82,10 +82,10 @@ reject_params(dc)
/* The declarator is checked to have no parameters, if it /* The declarator is checked to have no parameters, if it
is a function. is a function.
*/ */
if (dc->dc_fparams) { if (dc->dc_formal) {
error("non_empty formal parameter pack"); error("non_empty formal parameter pack");
del_idfstack(dc->dc_fparams); free_formals(dc->dc_formal);
dc->dc_fparams = 0; dc->dc_formal = 0;
} }
} }

View file

@ -132,7 +132,7 @@ dot2expr(expp)
string2expr(*expp); string2expr(*expp);
break; break;
case INTEGER: case INTEGER:
*expp = intexpr(dot.tk_ival, dot.tk_fund); int2expr(*expp);
break; break;
case FLOATING: case FLOATING:
float2expr(*expp); float2expr(*expp);
@ -214,6 +214,27 @@ string2expr(expr)
expr->SG_DATLAB = 0; expr->SG_DATLAB = 0;
} }
int2expr(expr)
struct expr *expr;
{
/* Dot contains an integer constant which is turned
into an expression.
*/
fill_int_expr(expr, dot.tk_ival, dot.tk_fund);
}
float2expr(expr)
struct expr *expr;
{
/* Dot contains a floating point constant which is turned
into an expression.
*/
expr->ex_type = double_type;
expr->ex_class = Float;
expr->FL_VALUE = dot.tk_fval;
expr->FL_DATLAB = 0;
}
struct expr* struct expr*
intexpr(ivalue, fund) intexpr(ivalue, fund)
arith ivalue; arith ivalue;
@ -227,6 +248,17 @@ intexpr(ivalue, fund)
expr->ex_file = dot.tk_file; expr->ex_file = dot.tk_file;
expr->ex_line = dot.tk_line; expr->ex_line = dot.tk_line;
fill_int_expr(expr, ivalue, fund);
return expr;
}
fill_int_expr(expr, ivalue, fund)
struct expr *expr;
arith ivalue;
{
/* Details derived from ivalue and fund are put into the
constant integer expression expr.
*/
switch (fund) { switch (fund) {
case INT: case INT:
expr->ex_type = int_type; expr->ex_type = int_type;
@ -258,19 +290,6 @@ intexpr(ivalue, fund)
expr->VL_VALUE = ivalue; expr->VL_VALUE = ivalue;
cut_size(expr); cut_size(expr);
return expr;
}
float2expr(expr)
struct expr *expr;
{
/* Dot contains a floating point constant which is turned
into an expression.
*/
expr->ex_type = double_type;
expr->ex_class = Float;
expr->FL_VALUE = dot.tk_fval;
expr->FL_DATLAB = 0;
} }
struct expr * struct expr *

View file

@ -552,14 +552,14 @@ declare_params(dc)
{ {
/* Declares the formal parameters if they exist. /* Declares the formal parameters if they exist.
*/ */
register struct idstack_item *is = dc->dc_fparams; register struct formal *fm = dc->dc_formal;
while (is) { while (fm) {
declare_parameter(is->is_idf); declare_parameter(fm->fm_idf);
is = is->next; fm = fm->next;
} }
del_idfstack(dc->dc_fparams); free_formals(dc->dc_formal);
dc->dc_fparams = 0; dc->dc_formal = 0;
} }
init_idf(idf) init_idf(idf)
@ -672,13 +672,13 @@ update_ahead(idf)
TYPE_IDENTIFIER : IDENTIFIER; TYPE_IDENTIFIER : IDENTIFIER;
} }
del_idfstack(is) free_formals(fm)
struct idstack_item *is; struct formal *fm;
{ {
while (is) { while (fm) {
register struct idstack_item *tmp = is->next; register struct formal *tmp = fm->next;
free_idstack_item(is); free_formal(fm);
is = tmp; fm = tmp;
} }
} }

View file

@ -22,13 +22,6 @@ extern char hmask[]; /* the random masks */
#define ENHASH(hs,ch,ps) (hs + (ch ^ hmask[ps])) #define ENHASH(hs,ch,ps) (hs + (ch ^ hmask[ps]))
#define STOPHASH(hs) (hs & HASHMASK) #define STOPHASH(hs) (hs & HASHMASK)
struct idstack_item { /* stack of identifiers */
struct idstack_item *next;
struct idf *is_idf;
};
/* ALLOCDEF "idstack_item" */
struct idf { struct idf {
struct idf *next; struct idf *next;
char *id_text; char *id_text;

View file

@ -189,14 +189,15 @@ compile(argc, argv)
#endif USE_TMP #endif USE_TMP
#ifdef DEBUG #ifdef DEBUG
if (options['u']) /* unstack L_UNIVERSAL */ if (options['u']) {
unstack_level(); unstack_level(); /* unstack L_GLOBAL */
}
if (options['f'] || options['t']) if (options['f'] || options['t'])
dumpidftab("end of main", options['f'] ? 0 : 0); dumpidftab("end of main", options['f'] ? 0 : 0);
#endif DEBUG #endif DEBUG
#ifndef NOPP #ifndef NOPP
} }
#endif NOPP #endif NOPP
PopLex(); PopLex();
} }

View file

@ -1,7 +1,6 @@
sed ' sed '
s:^.*ALLOCDEF.*"\(.*\)".*$:\ s:^.*ALLOCDEF.*"\(.*\)".*$:\
/* allocation definitions of struct \1 */\ /* allocation definitions of struct \1 */\
extern char *st_alloc();\
extern struct \1 *h_\1;\ extern struct \1 *h_\1;\
#define new_\1() ((struct \1 *) \\\ #define new_\1() ((struct \1 *) \\\
st_alloc((char **)\&h_\1, sizeof(struct \1)))\ st_alloc((char **)\&h_\1, sizeof(struct \1)))\

View file

@ -153,10 +153,9 @@ non_function(struct decspecs *ds; struct declarator *dc;)
: :
{reject_params(dc);} {reject_params(dc);}
initializer(dc->dc_idf, &expr)? initializer(dc->dc_idf, &expr)?
{ {
code_declaration(dc->dc_idf, expr, level, ds->ds_sc); code_declaration(dc->dc_idf, expr, level, ds->ds_sc);
free_expression(expr); }
}
[ [
',' ','
init_declarator(ds) init_declarator(ds)

View file

@ -1,4 +1,4 @@
/* DERIVED FROM $Header$ */ /* $Header$ */
/* S T A C K / U N S T A C K R O U T I N E S */ /* S T A C K / U N S T A C K R O U T I N E S */
#include <system.h> #include <system.h>
@ -250,19 +250,21 @@ unstack_world()
/* space must be allocated */ /* space must be allocated */
bss(idf); bss(idf);
namelist(idf->id_text); /* may be common */ namelist(idf->id_text); /* may be common */
def->df_alloc = ALLOC_DONE; /* *) */ def->df_alloc = ALLOC_DONE; /* see Note below */
} }
se = se->next; se = se->next;
} }
/* *) df_alloc must be set to ALLOC_DONE because the idf entry /* Note:
df_alloc must be set to ALLOC_DONE because the idf entry
may occur several times in the list. may occur several times in the list.
The reason for this is that the same name may be used The reason for this is that the same name may be used
for different purposes on the same level, e.g for different purposes on the same level, e.g.
struct s {int s;} s; struct s {int s;} s;
is a legal definition and contains 3 defining occurrences of s. is a legal definition and contains 3 defining occurrences
Each definition has been entered into the idfstack. of s.
Each definition has been entered into the identifier stack.
Although only one of them concerns a variable, we meet the Although only one of them concerns a variable, we meet the
s 3 times when scanning the idfstack. s 3 times when scanning the identifier stack.
*/ */
} }

View file

@ -153,7 +153,7 @@ while_statement
: :
WHILE WHILE
{ {
stat_stack(l_break, l_continue); stack_stmt(l_break, l_continue);
C_df_ilb(l_continue); C_df_ilb(l_continue);
} }
'(' '('
@ -175,7 +175,7 @@ while_statement
{ {
C_bra(l_continue); C_bra(l_continue);
C_df_ilb(l_break); C_df_ilb(l_break);
stat_unstack(); unstack_stmt();
free_expression(expr); free_expression(expr);
} }
; ;
@ -189,7 +189,7 @@ do_statement
: :
DO DO
{ C_df_ilb(l_body); { C_df_ilb(l_body);
stat_stack(l_break, l_continue); stack_stmt(l_break, l_continue);
} }
statement statement
WHILE WHILE
@ -212,7 +212,7 @@ do_statement
')' ')'
';' ';'
{ {
stat_unstack(); unstack_stmt();
free_expression(expr); free_expression(expr);
} }
; ;
@ -226,7 +226,7 @@ for_statement
} }
: :
FOR FOR
{ stat_stack(l_break, l_continue); { stack_stmt(l_break, l_continue);
} }
'(' '('
[ [
@ -263,7 +263,7 @@ for_statement
NO_LABEL, NO_LABEL); NO_LABEL, NO_LABEL);
C_bra(l_test); C_bra(l_test);
C_df_ilb(l_break); C_df_ilb(l_break);
stat_unstack(); unstack_stmt();
free_expression(e_init); free_expression(e_init);
free_expression(e_test); free_expression(e_test);
free_expression(e_incr); free_expression(e_incr);
@ -317,20 +317,14 @@ default_statement
break_statement break_statement
: :
BREAK BREAK
{ {code_break();}
if (!do_break())
error("invalid break");
}
';' ';'
; ;
continue_statement continue_statement
: :
CONTINUE CONTINUE
{ {code_continue();}
if (!do_continue())
error("invalid continue");
}
';' ';'
; ;

View file

@ -21,7 +21,7 @@ struct xxx {
}; };
char * char *
st_alloc(phead, size) head_alloc(phead, size)
char **phead; char **phead;
int size; int size;
{ {

View file

@ -1,9 +1,23 @@
/* $Header$ */ /* $Header$ */
/* S T R U C T U R E - S T O R A G E D E F I N I T I O N S */ /* S T R U C T U R E - S T O R A G E D E F I N I T I O N S */
/* Storage allocation is one of the most expensive operations in
the compiler and consequently much thought and experimentation
has gone into it. To simplify the hooking in of new super-fancy
algorithms, all allocating and freeing of storage for structs
goes through the macros
st_alloc(&head, size)
st_free(ptr, head, size)
which, hopefully, convey enough information.
*/
extern char *head_alloc();
#define st_alloc(headp, size) head_alloc((char **)headp, size)
#ifndef BOTCH_FREE #ifndef BOTCH_FREE
#define st_free(ptr, head, size) {ptr->next = head; head = ptr;} #define st_free(ptr, head, size) (ptr->next = head, head = ptr)
#else def BOTCH_FREE #else def BOTCH_FREE
#define st_free(ptr, head, size) {botch((char *)(ptr), size); \ #define st_free(ptr, head, size) (botch((char *)(ptr), size), \
ptr->next = head; head = ptr;} ptr->next = head, head = ptr)
#endif BOTCH_FREE #endif BOTCH_FREE

View file

@ -11,8 +11,6 @@ struct sdef { /* for selectors */
arith sd_offset; arith sd_offset;
}; };
extern char *st_alloc();
/* ALLOCDEF "sdef" */ /* ALLOCDEF "sdef" */
struct tag { /* for struct-, union- and enum tags */ struct tag { /* for struct-, union- and enum tags */

View file

@ -55,7 +55,7 @@ code_startswitch(expr)
break; break;
} }
stat_stack(l_break, NO_LABEL); stack_stmt(l_break, NO_LABEL);
sh->sh_break = l_break; sh->sh_break = l_break;
sh->sh_default = 0; sh->sh_default = 0;
sh->sh_table = l_table; sh->sh_table = l_table;
@ -123,7 +123,7 @@ code_endswitch()
ce = tmp; ce = tmp;
} }
free_switch_hdr(sh); free_switch_hdr(sh);
stat_unstack(); unstack_stmt();
} }
code_case(expr) code_case(expr)

View file

@ -10,6 +10,7 @@
#include "def.h" #include "def.h"
#include "sizes.h" #include "sizes.h"
#include "align.h" #include "align.h"
#include "storage.h"
struct type *function_of(), *array_of(); struct type *function_of(), *array_of();
#ifndef NOBITFIELD #ifndef NOBITFIELD