lots and lots of changes & improvements

This commit is contained in:
eck
1989-09-19 16:13:23 +00:00
parent 18439ffa3f
commit fa4e6eecb4
59 changed files with 1826 additions and 1571 deletions

View File

@@ -7,7 +7,6 @@
#include "lint.h"
#include <em_reg.h>
#include "nofloat.h"
#include "debug.h"
#include "idfsize.h"
#include "botch_free.h"
@@ -31,7 +30,6 @@
#include "Lpars.h"
#include "assert.h"
#include "specials.h" /* registration of special identifiers */
#include "noRoption.h"
int idfsize = IDFSIZE;
extern char options[];
@@ -226,24 +224,18 @@ declare_idf(ds, dc, lvl)
type = construct_type(POINTER, type, 0, (arith)0,
NO_PROTO);
break;
case ARRAY: /* RM 10.1 */
case ARRAY: /* 3.7.1 */
type = construct_type(POINTER, type->tp_up, 0, (arith)0,
NO_PROTO);
formal_array = 1;
break;
#ifndef NOFLOAT
case FLOAT: /* RM 10.1 */
type = double_type;
break;
#endif NOFLOAT
case FLOAT:
case CHAR:
case SHORT:
/* The RM is not clear about this: we must
convert the parameter from int (they have
been pushed as ints) to the specified type.
The conversion to type int or uint is not
allowed.
*/
/* The conversion is done in formal_cvt(). It is
* not done when the type is float and there is a
* prototype.
*/
break;
}
}
@@ -252,29 +244,27 @@ declare_idf(ds, dc, lvl)
*/
/* update the storage class */
if (type && type->tp_fund == FUNCTION) {
if (sc == 0 || (ds->ds_sc_given && sc == AUTO)) /* RM 8.1 */
sc = GLOBAL;
else
if (sc == REGISTER) {
error("function storage class cannot be register");
ds->ds_sc = sc = GLOBAL;
if (lvl != L_GLOBAL) { /* 3.5.1 */
if (sc == 0)
sc = GLOBAL;
else if (sc != EXTERN && sc != IMPLICIT) {
error("illegal storage class %s for function with block-scope"
, symbol2str(sc));
ds->ds_sc = sc = GLOBAL;
}
}
else if (sc == 0)
sc = GLOBAL;
}
else /* non-FUNCTION */
if (sc == 0)
sc = lvl == L_GLOBAL ? GLOBAL
: lvl == L_FORMAL1 || lvl == L_FORMAL2 ? FORMAL
: AUTO;
#ifndef NOROPTION
if (options['R']) { /* some special K & R tests */
/* is it also an enum? */
if (idf->id_enum && idf->id_enum->tg_level == level)
warning("%s is also an enum tag", idf->id_text);
/* is it a universal typedef? */
if (def && def->df_level == L_UNIVERSAL)
warning("redeclaring reserved word %s", idf->id_text);
}
#endif
/* is it a universal typedef? */
if (def && def->df_level == L_UNIVERSAL)
warning("redeclaring reserved word %s", idf->id_text);
#ifdef LINT
if ( def && def->df_level < lvl
@@ -330,6 +320,7 @@ declare_idf(ds, dc, lvl)
def->df_file = idf->id_file;
def->df_line = idf->id_line;
}
#if 0 /* be more strict in scope (at least for now) */
else
if ( lvl >= L_LOCAL &&
(type->tp_fund == FUNCTION || sc == EXTERN)
@@ -337,16 +328,13 @@ declare_idf(ds, dc, lvl)
/* extern declaration inside function is treated the
same way as global extern declaration
*/
#ifndef NOROPTION
if ( options['R'] &&
(sc == STATIC && type->tp_fund == FUNCTION)
)
if (sc == STATIC && type->tp_fund == FUNCTION)
if (!is_anon_idf(idf))
warning("non-global static function %s",
idf->id_text);
#endif
declare_idf(ds, dc, L_GLOBAL);
}
#endif
else { /* fill in the def block */
register struct def *newdef = new_def();
@@ -376,7 +364,8 @@ declare_idf(ds, dc, lvl)
switch (sc) {
case REGISTER:
case AUTO:
if (type->tp_size == (arith)-1) {
if (type->tp_size == (arith)-1
&& type->tp_fund != ARRAY) {
error("size of local %s unknown",
idf->id_text);
/** type = idf->id_def->df_type = int_type; **/
@@ -423,10 +412,12 @@ global_redecl(idf, new_sc, tp)
in storage class.
*/
register struct def *def = idf->id_def;
int retval;
if (!equal_type(tp, def->df_type))
if (!(retval = equal_type(tp, def->df_type)))
error("redeclaration of %s with different type", idf->id_text);
else update_proto(tp, def->df_type);
else if (retval == 1)
update_proto(tp, def->df_type);
if (tp->tp_fund == ARRAY) {
/* Multiple array declaration; this may be interesting */
if (tp->tp_size < 0) { /* new decl has [] */
@@ -451,6 +442,7 @@ global_redecl(idf, new_sc, tp)
*/
if (new_sc == IMPLICIT)
return; /* no new information */
switch (def->df_sc) { /* the old storage class */
case EXTERN:
switch (new_sc) { /* the new storage class */
@@ -458,15 +450,8 @@ global_redecl(idf, new_sc, tp)
case GLOBAL:
break;
case STATIC:
if (def->df_initialized) {
error("cannot redeclare %s to static",
idf->id_text);
}
else {
warning("%s redeclared to static",
idf->id_text);
}
def->df_sc = new_sc;
warning("redeclaration of %s to static ignored"
, idf->id_text);
break;
default:
crash("bad storage class");
@@ -481,17 +466,8 @@ global_redecl(idf, new_sc, tp)
case GLOBAL:
break;
case STATIC:
if (def->df_initialized)
error("cannot redeclare %s to static",
idf->id_text);
else {
#ifndef NOROPTION
if (options['R'])
warning("%s redeclared to static",
idf->id_text);
#endif
def->df_sc = STATIC;
}
warning("redeclaration of %s to static ignored"
, idf->id_text);
break;
default:
crash("bad storage class");
@@ -500,21 +476,13 @@ global_redecl(idf, new_sc, tp)
break;
case STATIC:
switch (new_sc) { /* the new storage class */
case EXTERN:
if (def->df_initialized)
error("cannot redeclare %s to extern",
idf->id_text);
else {
warning("%s redeclared to extern",
idf->id_text);
def->df_sc = EXTERN;
}
break;
case GLOBAL:
warning("%s redeclared extern", idf->id_text);
def->df_sc = new_sc;
break;
case EXTERN: /* complain at definition */
break;
case STATIC:
if (def->df_type->tp_fund != FUNCTION)
warning("%s was already static",
idf->id_text);
break;
default:
crash("bad storage class");
@@ -528,11 +496,6 @@ global_redecl(idf, new_sc, tp)
def->df_sc = new_sc;
break;
case STATIC:
#ifndef NOROPTION
if (options['R'])
warning("%s was implicitly declared as extern",
idf->id_text);
#endif
def->df_sc = new_sc;
break;
default:
@@ -568,18 +531,16 @@ good_formal(def, idf)
}
declare_params(dc)
register struct declarator *dc;
struct declarator *dc;
{
/* Declares the formal parameters if they exist.
*/
register struct formal *fm = dc->dc_formal;
while (fm) {
declare_parameter(fm->fm_idf);
fm = fm->next;
}
free_formals(dc->dc_formal);
dc->dc_formal = 0;
}
init_idf(idf)
@@ -617,7 +578,76 @@ declare_enum(tp, idf, l)
idf->id_def->df_address = l;
}
declare_formals(fp)
check_formals(idf, dc)
struct idf *idf;
struct declarator *dc;
{
register struct formal *fm = dc->dc_formal;
register struct proto *pl = idf->id_def->df_type->tp_proto;
register struct decl_unary *du = dc->dc_decl_unary;
if (!du) { /* error or typdef'ed function */
error("illegal definition of %s", idf->id_text);
return;
}
while (du && du->du_fund != FUNCTION)
du = du->next;
ASSERT(du);
if (du->du_proto) return;
warning("'%s' old-fashioned function definition", dc->dc_idf->id_text);
if (pl) {
if (pl->pl_flag & PL_ELLIPSIS) {
if (!(du->du_proto) && !(pl->pl_flag & PL_ERRGIVEN))
error("ellipsis terminator in previous declaration");
pl = pl->next;
}
else if (pl->pl_flag & PL_VOID) {
pl = pl->next; /* should be 0 */
}
while(fm && pl) {
if (!equal_type(promoted_type(fm->fm_idf->id_def->df_type)
, pl->pl_type)) {
if (!(pl->pl_flag & PL_ERRGIVEN))
error("incorrect type for parameter %s"
, fm->fm_idf->id_text);
pl->pl_flag |= PL_ERRGIVEN;
}
fm = fm->next;
pl = pl->next;
}
if (pl || fm) {
error("incorrect number of parameters");
}
} else { /* make a pseudo-prototype */
register struct proto *lpl;
while (fm) {
if (pl == 0) pl = lpl = new_proto();
else {
lpl->next = new_proto();
lpl = lpl->next;
}
lpl->pl_flag = PL_FORMAL;
lpl->pl_idf = fm->fm_idf;
lpl->pl_type =
promoted_type(fm->fm_idf->id_def->df_type);
fm = fm->next;
}
if (pl == 0) { /* make func(void) */
pl = new_proto();
pl->pl_flag = PL_VOID;
}
idf->id_def->df_type->tp_pseudoproto = pl;
}
free_formals(dc->dc_formal);
dc->dc_formal = 0;
}
declare_formals(idf, fp)
struct idf *idf;
arith *fp;
{
/* Declares those formals as int that haven't been declared
@@ -628,6 +658,7 @@ declare_formals(fp)
register struct stack_entry *se = stack_level_of(L_FORMAL1)->sl_entry;
arith f_offset = (arith)0;
register int nparams = 0;
int hasproto = idf->id_def->df_type->tp_proto != 0;
#ifdef DEBUG
if (options['t'])
@@ -636,13 +667,22 @@ declare_formals(fp)
while (se) {
register struct def *def = se->se_idf->id_def;
/* this stacklevel may also contain tags. ignore them */
if (!def || def->df_level < L_FORMAL1 ) {
se = se->next;
continue;
}
def->df_address = f_offset;
/* the alignment convention for parameters is: align on
word boundaries, i.e. take care that the following
parameter starts on a new word boundary.
*/
f_offset = align(f_offset + def->df_type->tp_size, (int) word_size);
formal_cvt(def); /* cvt int to char or short, if necessary */
/* cvt int to char or short and double to float, if necessary
*/
formal_cvt(hasproto, def);
se = se->next;
def->df_level = L_FORMAL2; /* CJ */
RegisterAccount(def->df_address, def->df_type->tp_size,
@@ -662,11 +702,10 @@ regtype(tp)
case INT:
case LONG:
return reg_any;
#ifndef NOFLOAT
case FLOAT:
case DOUBLE:
case LNGDBL:
return reg_float;
#endif NOFLOAT
case POINTER:
return reg_pointer;
}