fixed bugs with prototype scopes

This commit is contained in:
eck 1990-09-12 16:36:16 +00:00
parent bd18f6c521
commit e144c7cc4c
6 changed files with 55 additions and 25 deletions

View file

@ -142,8 +142,9 @@ prepend_scopes()
register struct idf *id = se->se_idf;
register struct def *df = id->id_def;
if (df && (df->df_initialized || df->df_used || df->df_alloc))
if (df && (df->df_initialized || df->df_used || df->df_alloc)) {
code_scope(id->id_text, df);
}
se = se->next;
}
#ifdef USE_TMP
@ -201,6 +202,23 @@ begin_proc(ds, idf) /* to be called when entering a procedure */
register char *name = idf->id_text;
register struct def *def = idf->id_def;
/* idf->id_def does not indicate the right def structure
* when the function being defined has a parameter of the
* same name in an old-style function definition.
*/
while (def->df_level != L_GLOBAL) def = def->next;
/* When we have a new-style function definition, the parameters
* are defined first, which means that it may look as if they have
* the greatest scope. Correct this.
*/
if (idf->id_def == def && def->next && def->next->df_level == L_PROTO) {
struct def *tmpdef = def->next;
def->next = tmpdef->next;
tmpdef->next = def;
idf->id_def = tmpdef;
}
#ifndef PREPEND_SCOPES
code_scope(name, def);
#endif PREPEND_SCOPES

View file

@ -193,7 +193,6 @@ init_declarator(register struct decspecs *ds;)
declarator(&Dc)
{
reject_params(&Dc);
def_proto(&Dc);
declare_idf(ds, &Dc, level);
#ifdef LINT
lint_declare_idf(Dc.dc_idf, ds->ds_sc);

View file

@ -97,13 +97,22 @@ reject_params(dc)
register struct declarator *dc;
{
/* The declarator is checked to have no parameters, if it
is a function.
is an old-style function. If it is a new-style function,
the identifiers are removed. The function is not called in
case of a function definition.
*/
register struct decl_unary *du = dc->dc_decl_unary;
if (dc->dc_formal) {
error("non_empty formal parameter pack");
free_formals(dc->dc_formal);
dc->dc_formal = 0;
}
while (du) {
if (du->du_fund == FUNCTION)
remove_proto_idfs(du->du_proto);
du = du->next;
}
}
check_array_subscript(expr)

View file

@ -288,10 +288,13 @@ declare_idf(ds, dc, lvl)
}
#endif LINT
if (def &&
if ((def &&
( def->df_level == lvl ||
( lvl != L_GLOBAL && def->df_level > lvl )
)
))
|| (lvl == L_GLOBAL
&& def && def->df_level == L_PROTO
&& def->next && def->next->df_level == L_GLOBAL)
) {
/* There is already a declaration for idf on this
level, or even more inside.
@ -350,7 +353,6 @@ declare_idf(ds, dc, lvl)
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);
@ -415,6 +417,7 @@ global_redecl(idf, new_sc, tp)
*/
register struct def *def = idf->id_def;
while (def->df_level != L_GLOBAL) def = def->next;
if (!equal_type(tp, def->df_type, 0)) {
error("redeclaration of %s with different type", idf->id_text);
return;
@ -551,6 +554,7 @@ init_idf(idf)
*/
register struct def *def = idf->id_def; /* the topmost */
while (def->df_level <= L_PROTO) def = def->next;
if (def->df_initialized)
error("multiple initialization of %s", idf->id_text);
if (def->df_sc == TYPEDEF) {

View file

@ -111,6 +111,24 @@ program:
used again and again, while the declarator is stored in a struct
declarator, only to be passed to declare_idf together with the
struct decspecs.
With the introduction of prototypes, extra problems for the scope
administration were introduced as well. We can have, for example,
int x(double x);
and
int x(double x) { ... use(x) ... }
In the first case, the parameter name can be forgotten, whereas in
the second case, the parameter should have a block scope. The
problem lies in the fact that the parameter's type is known before
the type of the function, which causes the def structure to be on
the end of the list. Our solution is as follows:
1- In case of a declaration, throw the parameter identifier away
before the declaration of the outer x.
2- In case of a definition, the function begin_proc() changes the
def list for the identifier. This means that declare_idf()
contains an extra test in case we already saw a declaration of
such a function, because this function is called before
begin_proc().
*/
external_definition
@ -156,7 +174,6 @@ external_definition
non_function(register struct decspecs *ds; register struct declarator *dc;)
:
{ reject_params(dc);
def_proto(dc);
}
[
initializer(dc->dc_idf, ds->ds_sc)

View file

@ -88,8 +88,6 @@ add_proto(pl, ds, dc, lvl)
/* Perform some special conversions for parameters.
*/
if (type->tp_fund == FUNCTION) {
if (type->tp_proto)
remove_proto_idfs(type->tp_proto);
type = construct_type(POINTER, type, 0, (arith) 0, NO_PROTO);
} else if (type->tp_fund == ARRAY) {
type = construct_type(POINTER, type->tp_up, 0, (arith) 0, NO_PROTO);
@ -247,21 +245,6 @@ declare_protos(dc)
}
def_proto(dc)
register struct declarator *dc;
{
/* Prototype declarations may have arguments, but the idf's
in the parameter type list can be ignored.
*/
register struct decl_unary *du = dc->dc_decl_unary;
while (du) {
if (du->du_fund == FUNCTION)
remove_proto_idfs(du->du_proto);
du = du->next;
}
}
update_proto(tp, otp)
register struct type *tp, *otp;
{
@ -368,7 +351,7 @@ remove_proto_idfs(pl)
pl->pl_idf->id_text);
#endif
def = pl->pl_idf->id_def;
if (def && def->df_level <= L_PROTO){
if (def && def->df_level <= L_PROTO) {
pl->pl_idf->id_def = def->next;
free_def(def);
}