}
dumptags(idf->id_struct);
}
+ if (idf->id_enum) {
+ if (!started++) {
+ newline();
+ print("%s:", idf->id_text);
+ }
+ dumptags(idf->id_enum);
+ }
}
dumpdefs(def, opt)
);
print("%s, line %u",
def->df_file ? def->df_file : "NO_FILE", def->df_line);
- dump_type(def->df_type);
+ dumptype(def->df_type);
def = def->next;
}
dumplevel--;
dumplevel--;
}
-dump_proto(pl)
+dumpproto(pl)
register struct proto *pl;
{
register struct type *type;
? "ellipsis" : "unknown" ));
newline();
if (type = pl->pl_type){
- dump_type(type);
+ dumptype(type);
newline();
}
if (pl->pl_idf) {
print("dump proto type list (end)\n");
}
-dump_type(tp)
+dumptype(tp)
register struct type *tp;
{
int ops = 1;
if (!tp) {
print("<NILTYPE>");
newline();
+ dumplevel--;
return;
}
if (tp->tp_proto) {
print("with prototype");
dumplevel++;
- dump_proto(tp->tp_proto);
+ dumpproto(tp->tp_proto);
dumplevel--;
newline();
}
if (tp->tp_idf)
print("%s ", tp->tp_idf->id_text);
#ifndef NOBITFIELD
- if (tp->tp_field) {
+ if (tp->tp_fund == FIELD && tp->tp_field) {
struct field *fd = tp->tp_field;
print("[s=%ld,w=%ld] of ",
sprint(buf, "%s %s ", buf,
tp->tp_idf->id_text);
#ifndef NOBITFIELD
- if (tp->tp_field) {
+ if (tp->tp_fund == FIELD && tp->tp_field) {
struct field *fd = tp->tp_field;
sprint(buf, "%s [s=%ld,w=%ld] of ", buf,
#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 */
+
+#define PFDF 'd' /* Prototype Function Definition */
+
+#define EFDF 'f' /* External Function Definition */
+#define EVDF 'g' /* External Variable Definition */
+#define EFDC 'h' /* External Function Declaration */
+#define EVDC 'i' /* External Variable Declaration */
+
+#define IFDC 'm' /* Implicit Function Declaration */
+
+#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 */
#include "arith.h"
#include "assert.h"
#include "type.h"
+#include "proto.h"
#include "declar.h"
#include "decspecs.h"
#include "LLlex.h"
PRIVATE outarg();
PRIVATE outargstring();
PRIVATE outargtype();
-PRIVATE fill_arg();
+PRIVATE add_expr_arg();
+PRIVATE def2decl();
lint_declare_idf(idf, sc)
struct idf *idf;
{
/* At this place the following fields of the output definition can be
* 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 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 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.
*/
register struct def *def = idf->id_def;
OutDef.od_valreturned = NORETURN;
}
+PRIVATE
def2decl(sc)
int sc;
{
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.
*/
register struct stack_entry *se = stack_level_of(L_FORMAL1)->sl_entry;
register struct type *type = se->se_idf->id_def->df_type;
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_FORMATvar
&& ( type->tp_fund != POINTER
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)
struct idf *idf;
{
output_def(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.
*/
if (od->od_class == XXDF || !od->od_name || od->od_name[0] == '#')
od->od_class = LVDF;
break;
case SFDF:
- /* remove tp_entries */
+ /* free the 'struct argument's */
while (od->od_arg) {
register struct argument *tmp = od->od_arg;
od->od_arg = od->od_arg->next;
}
printf("%s:%d:%c", od->od_name, od->od_statnr, od->od_class);
switch (od->od_class) {
+ case LFDF:
+ case PFDF:
case EFDF:
case SFDF:
- case LFDF:
if (f_VARARGSn != -1) {
printf(":%d", -1 - f_VARARGSn);
outargs(od->od_arg, f_VARARGSn);
}
break;
+ case ArgEllipsis:
+ printf("."); /* one is enough for computers */
+ break;
+
default:
NOTREACHED();
/*NOTREACHED*/
printf("%s ", symbol2str(tp->tp_fund));
if (is_anon_idf(tp->tp_idf)) {
/* 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;
case CHAR:
case INT:
case SHORT:
case LONG:
+ case ULONG:
case FLOAT:
case DOUBLE:
+ case LNGDBL:
case VOID:
case ERRONEOUS:
- if (tp->tp_unsigned)
+ if (tp->tp_unsigned) {
printf("unsigned ");
+ }
printf("%s", symbol2str(tp->tp_fund));
break;
default:
OutCall.od_arg = (struct argument *)0;
OutCall.od_nrargs = 0;
- if ((ex = ex->OP_RIGHT) != 0) { /* function call with arguments */
- /* store types of argument expressions in tp_entries */
+ if ((ex = ex->OP_RIGHT) != 0) {
+ /* function call with arguments: */
+ /* store types of argument expressions in 'struct argument's */
while (ex->ex_class == Oper && ex->OP_OPER == PARCOMMA) {
- fill_arg(ex->OP_RIGHT);
+ add_expr_arg(ex->OP_RIGHT);
ex = ex->OP_LEFT;
}
- fill_arg(ex);
+ add_expr_arg(ex);
}
OutCall.od_valused = used; /* USED, IGNORED or VOIDED */
}
PRIVATE
-fill_arg(e)
+add_expr_arg(e)
struct expr *e;
{
register struct argument *arg;