prototypes now handled by lint

This commit is contained in:
dick 1991-07-05 11:55:17 +00:00
parent a0460b8bfc
commit ca104453ca
7 changed files with 119 additions and 54 deletions

View file

@ -145,6 +145,13 @@ dumpidf(idf, opt)
} }
dumptags(idf->id_struct); dumptags(idf->id_struct);
} }
if (idf->id_enum) {
if (!started++) {
newline();
print("%s:", idf->id_text);
}
dumptags(idf->id_enum);
}
} }
dumpdefs(def, opt) dumpdefs(def, opt)
@ -163,7 +170,7 @@ dumpdefs(def, opt)
); );
print("%s, line %u", print("%s, line %u",
def->df_file ? def->df_file : "NO_FILE", def->df_line); def->df_file ? def->df_file : "NO_FILE", def->df_line);
dump_type(def->df_type); dumptype(def->df_type);
def = def->next; def = def->next;
} }
dumplevel--; dumplevel--;
@ -229,7 +236,7 @@ dumpsdefs(sdef, sdk)
dumplevel--; dumplevel--;
} }
dump_proto(pl) dumpproto(pl)
register struct proto *pl; register struct proto *pl;
{ {
register struct type *type; register struct type *type;
@ -246,7 +253,7 @@ dump_proto(pl)
? "ellipsis" : "unknown" )); ? "ellipsis" : "unknown" ));
newline(); newline();
if (type = pl->pl_type){ if (type = pl->pl_type){
dump_type(type); dumptype(type);
newline(); newline();
} }
if (pl->pl_idf) { if (pl->pl_idf) {
@ -261,7 +268,7 @@ dump_proto(pl)
print("dump proto type list (end)\n"); print("dump proto type list (end)\n");
} }
dump_type(tp) dumptype(tp)
register struct type *tp; register struct type *tp;
{ {
int ops = 1; int ops = 1;
@ -271,6 +278,7 @@ dump_type(tp)
if (!tp) { if (!tp) {
print("<NILTYPE>"); print("<NILTYPE>");
newline(); newline();
dumplevel--;
return; return;
} }
@ -290,7 +298,7 @@ dump_type(tp)
if (tp->tp_proto) { if (tp->tp_proto) {
print("with prototype"); print("with prototype");
dumplevel++; dumplevel++;
dump_proto(tp->tp_proto); dumpproto(tp->tp_proto);
dumplevel--; dumplevel--;
newline(); newline();
} }
@ -302,7 +310,7 @@ dump_type(tp)
if (tp->tp_idf) if (tp->tp_idf)
print("%s ", tp->tp_idf->id_text); print("%s ", tp->tp_idf->id_text);
#ifndef NOBITFIELD #ifndef NOBITFIELD
if (tp->tp_field) { if (tp->tp_fund == FIELD && tp->tp_field) {
struct field *fd = tp->tp_field; struct field *fd = tp->tp_field;
print("[s=%ld,w=%ld] of ", print("[s=%ld,w=%ld] of ",
@ -356,7 +364,7 @@ type2str(tp)
sprint(buf, "%s %s ", buf, sprint(buf, "%s %s ", buf,
tp->tp_idf->id_text); tp->tp_idf->id_text);
#ifndef NOBITFIELD #ifndef NOBITFIELD
if (tp->tp_field) { if (tp->tp_fund == FIELD && tp->tp_field) {
struct field *fd = tp->tp_field; struct field *fd = tp->tp_field;
sprint(buf, "%s [s=%ld,w=%ld] of ", buf, sprint(buf, "%s [s=%ld,w=%ld] of ", buf,

View file

@ -8,14 +8,21 @@
#define LFDF 'a' /* Library Function Definition */ #define LFDF 'a' /* Library Function Definition */
#define LVDF 'b' /* Library Variable Definition */ #define LVDF 'b' /* Library Variable Definition */
#define EFDF 'c' /* External Function Definition */
#define EVDF 'd' /* External Variable Definition */ #define PFDF 'd' /* Prototype Function Definition */
#define EFDC 'e' /* External Function Declaration */
#define EVDC 'f' /* External Variable Declaration */ #define EFDF 'f' /* External Function Definition */
#define IFDC 'g' /* Implicit Function Declaration */ #define EVDF 'g' /* External Variable Definition */
#define SFDF 'h' /* Static Function Definition */ #define EFDC 'h' /* External Function Declaration */
#define SVDF 'i' /* Static Variable Definition */ #define EVDC 'i' /* External Variable Declaration */
#define FC 'j' /* Function Call */
#define VU 'k' /* Variable Usage */ #define IFDC 'm' /* Implicit Function Declaration */
#define XXDF 'l' /* Ignore Class */
#define SFDF 'q' /* Static Function Definition */
#define SVDF 'r' /* Static Variable Definition */
#define FC 'u' /* Function Call */
#define VU 'v' /* Variable Usage */
#define XXDF 'z' /* Ignore Class */

View file

@ -364,6 +364,10 @@ lint_ptr_conv(from, to)
break; break;
} }
if (from == VOID) {
/* OK any which way */
}
else
if (from == CHAR) { if (from == CHAR) {
hwarning("pointer to char may not align correctly for a %s", hwarning("pointer to char may not align correctly for a %s",
symbol2str(to)); symbol2str(to));

View file

@ -17,6 +17,7 @@
#include "arith.h" #include "arith.h"
#include "assert.h" #include "assert.h"
#include "type.h" #include "type.h"
#include "proto.h"
#include "declar.h" #include "declar.h"
#include "decspecs.h" #include "decspecs.h"
#include "LLlex.h" #include "LLlex.h"
@ -50,7 +51,8 @@ PRIVATE outargs();
PRIVATE outarg(); PRIVATE outarg();
PRIVATE outargstring(); PRIVATE outargstring();
PRIVATE outargtype(); PRIVATE outargtype();
PRIVATE fill_arg(); PRIVATE add_expr_arg();
PRIVATE def2decl();
lint_declare_idf(idf, sc) lint_declare_idf(idf, sc)
struct idf *idf; struct idf *idf;
@ -90,11 +92,11 @@ lint_ext_def(idf, sc)
{ {
/* At this place the following fields of the output definition can be /* At this place the following fields of the output definition can be
* filled: * filled:
* name, stat_number, class, file, line, type. * od_name, od_statnr, od_class, od_file, od_line, od_type.
* For variable definitions and declarations this will be all. * For variable definitions and declarations this will be all.
* For functions the fields nrargs and argtps are filled after parsing * For functions the fields od_nrargs and od_arg are filled after parsing
* the arguments. * the arguments.
* The returns-field is known at the end of the function definition. * The od_valreturned field is known at the end of the function definition.
* sc indicates the storage class defined by the declaration specifier. * sc indicates the storage class defined by the declaration specifier.
*/ */
register struct def *def = idf->id_def; register struct def *def = idf->id_def;
@ -126,6 +128,7 @@ lint_ext_def(idf, sc)
OutDef.od_valreturned = NORETURN; OutDef.od_valreturned = NORETURN;
} }
PRIVATE
def2decl(sc) def2decl(sc)
int sc; int sc;
{ {
@ -159,7 +162,7 @@ local_EFDC(idf)
lint_formals() lint_formals()
{ {
/* Make a list of tp_entries containing the types of the formal /* Make a list of 'struct argument's containing the types of the formal
* parameters of the function definition just parsed. * parameters of the function definition just parsed.
*/ */
register struct stack_entry *se = stack_level_of(L_FORMAL1)->sl_entry; register struct stack_entry *se = stack_level_of(L_FORMAL1)->sl_entry;
@ -170,24 +173,6 @@ lint_formals()
register struct type *type = se->se_idf->id_def->df_type; register struct type *type = se->se_idf->id_def->df_type;
register struct argument *arg = new_argument(); register struct argument *arg = new_argument();
/* 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.
*/
switch (type->tp_fund) {
case CHAR:
case SHORT:
type = (type->tp_unsigned ? uint_type : int_type);
break;
case FLOAT:
type = double_type;
break;
}
if (f_FORMAT && nrargs == f_FORMATn) { if (f_FORMAT && nrargs == f_FORMATn) {
if ( !f_FORMATvar if ( !f_FORMATvar
&& ( type->tp_fund != POINTER && ( type->tp_fund != POINTER
@ -258,6 +243,46 @@ lint_formals()
OutDef.od_nrargs = nrargs; OutDef.od_nrargs = nrargs;
} }
output_proto(idf, def)
struct idf *idf;
struct def *def;
{
/* fund == FUNCTION && sc != STATIC */
register struct proto *pl = def->df_type->tp_proto;
register int nrargs = 0;
if (!pl) return;
OutDef.od_name = idf->id_text;
OutDef.od_statnr = 0;
OutDef.od_class = PFDF;
OutDef.od_file = def->df_file;
OutDef.od_line = def->df_line;
OutDef.od_type = def->df_type->tp_up;
OutDef.od_valreturned = NORETURN;/*???*/
while (pl) {
register struct type *type = pl->pl_type;
register struct argument *arg = new_argument();
if (type) {
arg->ar_type = type;
arg->ar_class = ArgFormal;
}
else {
arg->ar_class = ArgEllipsis;
}
arg->next = OutDef.od_arg;
OutDef.od_arg = arg;
nrargs++;
pl = pl->next;
}
OutDef.od_nrargs = nrargs;
outdef();
}
output_use(idf) output_use(idf)
struct idf *idf; struct idf *idf;
{ {
@ -286,7 +311,7 @@ PRIVATE
output_def(od) output_def(od)
struct outdef *od; struct outdef *od;
{ {
/* As the types are output the tp_entries are removed, because they /* As the types are output the 'struct argument's are freed, because they
* are then not needed anymore. * are then not needed anymore.
*/ */
if (od->od_class == XXDF || !od->od_name || od->od_name[0] == '#') if (od->od_class == XXDF || !od->od_name || od->od_name[0] == '#')
@ -301,7 +326,7 @@ output_def(od)
od->od_class = LVDF; od->od_class = LVDF;
break; break;
case SFDF: case SFDF:
/* remove tp_entries */ /* free the 'struct argument's */
while (od->od_arg) { while (od->od_arg) {
register struct argument *tmp = od->od_arg; register struct argument *tmp = od->od_arg;
od->od_arg = od->od_arg->next; od->od_arg = od->od_arg->next;
@ -314,9 +339,10 @@ output_def(od)
} }
printf("%s:%d:%c", od->od_name, od->od_statnr, od->od_class); printf("%s:%d:%c", od->od_name, od->od_statnr, od->od_class);
switch (od->od_class) { switch (od->od_class) {
case LFDF:
case PFDF:
case EFDF: case EFDF:
case SFDF: case SFDF:
case LFDF:
if (f_VARARGSn != -1) { if (f_VARARGSn != -1) {
printf(":%d", -1 - f_VARARGSn); printf(":%d", -1 - f_VARARGSn);
outargs(od->od_arg, f_VARARGSn); outargs(od->od_arg, f_VARARGSn);
@ -407,6 +433,10 @@ outarg(arg)
} }
break; break;
case ArgEllipsis:
printf("."); /* one is enough for computers */
break;
default: default:
NOTREACHED(); NOTREACHED();
/*NOTREACHED*/ /*NOTREACHED*/
@ -460,21 +490,28 @@ outargtype(tp)
printf("%s ", symbol2str(tp->tp_fund)); printf("%s ", symbol2str(tp->tp_fund));
if (is_anon_idf(tp->tp_idf)) { if (is_anon_idf(tp->tp_idf)) {
/* skip the #<num>, replace it by '#anonymous id' */ /* skip the #<num>, replace it by '#anonymous id' */
printf("#anonymous id%s", strindex(tp->tp_idf->id_text, ' ')); printf("#anonymous id%s",
strindex(tp->tp_idf->id_text, ' ')
);
}
else {
printf(tp->tp_idf->id_text);
} }
else printf(tp->tp_idf->id_text);
break; break;
case CHAR: case CHAR:
case INT: case INT:
case SHORT: case SHORT:
case LONG: case LONG:
case ULONG:
case FLOAT: case FLOAT:
case DOUBLE: case DOUBLE:
case LNGDBL:
case VOID: case VOID:
case ERRONEOUS: case ERRONEOUS:
if (tp->tp_unsigned) if (tp->tp_unsigned) {
printf("unsigned "); printf("unsigned ");
}
printf("%s", symbol2str(tp->tp_fund)); printf("%s", symbol2str(tp->tp_fund));
break; break;
default: default:
@ -526,19 +563,20 @@ fill_outcall(ex, used)
OutCall.od_arg = (struct argument *)0; OutCall.od_arg = (struct argument *)0;
OutCall.od_nrargs = 0; OutCall.od_nrargs = 0;
if ((ex = ex->OP_RIGHT) != 0) { /* function call with arguments */ if ((ex = ex->OP_RIGHT) != 0) {
/* store types of argument expressions in tp_entries */ /* function call with arguments: */
/* store types of argument expressions in 'struct argument's */
while (ex->ex_class == Oper && ex->OP_OPER == PARCOMMA) { while (ex->ex_class == Oper && ex->OP_OPER == PARCOMMA) {
fill_arg(ex->OP_RIGHT); add_expr_arg(ex->OP_RIGHT);
ex = ex->OP_LEFT; ex = ex->OP_LEFT;
} }
fill_arg(ex); add_expr_arg(ex);
} }
OutCall.od_valused = used; /* USED, IGNORED or VOIDED */ OutCall.od_valused = used; /* USED, IGNORED or VOIDED */
} }
PRIVATE PRIVATE
fill_arg(e) add_expr_arg(e)
struct expr *e; struct expr *e;
{ {
register struct argument *arg; register struct argument *arg;

View file

@ -10,6 +10,7 @@
#define ArgExpr 1 /* actual */ #define ArgExpr 1 /* actual */
#define ArgConst 2 /* integer constant */ #define ArgConst 2 /* integer constant */
#define ArgString 3 /* string */ #define ArgString 3 /* string */
#define ArgEllipsis 4 /* ellipsis */
struct argument { struct argument {
struct argument *next; struct argument *next;

View file

@ -199,7 +199,8 @@ lint_1_global(idf, def)
struct def *def; struct def *def;
{ {
register int sc = def->df_sc; register int sc = def->df_sc;
register int fund = def->df_type->tp_fund; register struct type *tp = def->df_type;
register int fund = tp->tp_fund;
switch (sc) { switch (sc) {
case STATIC: case STATIC:
@ -211,6 +212,10 @@ lint_1_global(idf, def)
if (fund == ERRONEOUS) if (fund == ERRONEOUS)
break; break;
if (fund == FUNCTION && sc != STATIC) {
output_proto(idf, def);
}
if (def->df_set || def->df_used) { if (def->df_set || def->df_used) {
/* Output a line to the intermediate file for /* Output a line to the intermediate file for
* used external variables (including functions) * used external variables (including functions)

View file

@ -99,12 +99,12 @@ code_endswitch()
if (sh->sh_default == 0) /* no default occurred yet */ if (sh->sh_default == 0) /* no default occurred yet */
sh->sh_default = sh->sh_break; sh->sh_default = sh->sh_break;
#ifndef LINT
C_bra(sh->sh_break); /* skip the switch table now */ C_bra(sh->sh_break); /* skip the switch table now */
C_df_ilb(sh->sh_table); /* switch table entry */ C_df_ilb(sh->sh_table); /* switch table entry */
/* evaluate the switch expr. */ /* evaluate the switch expr. */
#ifndef LINT
code_expr(sh->sh_expr, RVAL, TRUE, NO_LABEL, NO_LABEL); code_expr(sh->sh_expr, RVAL, TRUE, NO_LABEL, NO_LABEL);
#endif
if (sh->sh_nrofentries <= 1) { if (sh->sh_nrofentries <= 1) {
if (sh->sh_nrofentries) { if (sh->sh_nrofentries) {
load_cst(sh->sh_lowerbd, size); load_cst(sh->sh_lowerbd, size);
@ -150,6 +150,8 @@ code_endswitch()
} }
} }
C_df_ilb(sh->sh_break); C_df_ilb(sh->sh_break);
#endif
switch_stack = sh->next; /* unstack the switch descriptor */ switch_stack = sh->next; /* unstack the switch descriptor */
for (ce = sh->sh_entries; ce;) { /* free allocated switch structure */ for (ce = sh->sh_entries; ce;) { /* free allocated switch structure */
register struct case_entry *tmp = ce->next; register struct case_entry *tmp = ce->next;