2 * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
3 * See the copyright notice in the ACK home directory, in the file "Copyright".
5 /* $Id: l_outdef.c,v 3.12 1994/06/24 12:04:50 ceriel Exp $ */
6 /* Lint outdef construction */
13 #include "interface.h"
15 #include <flt_arith.h>
34 #include "l_comment.h"
38 extern char *bts2str();
39 extern char *symbol2str();
40 extern char *strindex();
42 int stat_number = 9999; /* static scope number */
45 PRIVATE struct outdef OutCall;
51 PRIVATE outargstring();
53 PRIVATE add_expr_arg();
55 lint_declare_idf(idf, sc)
59 register struct def *def = idf->id_def;
60 register int is_function = def->df_type->tp_fund == FUNCTION;
62 if (level == L_GLOBAL) {
63 lint_ext_def(idf, sc);
70 if (level >= L_LOCAL && sc != STATIC && is_function) {
75 lint_non_function_decl(ds, dc)
77 struct declarator *dc;
79 register struct def *def = dc->dc_idf->id_def;
80 register int is_function = def->df_type->tp_fund == FUNCTION;
84 if (def->df_sc != TYPEDEF)
91 /* At this place the following fields of the output definition can be
93 * name, stat_number, class, file, line, type.
94 * For variable definitions and declarations this will be all.
95 * For functions the fields nrargs and argtps are filled after parsing
97 * The returns-field is known at the end of the function definition.
98 * sc indicates the storage class defined by the declaration specifier.
100 register struct def *def = idf->id_def;
101 register struct type *type = def->df_type;
103 OutDef.od_name = idf->id_text;
104 OutDef.od_statnr = (sc == STATIC ? stat_number : 0);
106 switch (type->tp_fund) {
108 OutDef.od_class = XXDF;
111 /* For the moment assume it will be a definition.
112 * If no compound_statement follows, it is a declaration,
113 * in which case the class will be adjusted by def2decl().
115 OutDef.od_class = (sc == STATIC ? SFDF : EFDF);
117 default: /* a variable */
119 sc == EXTERN ? EVDC :
120 sc == STATIC ? SVDF : EVDF;
123 OutDef.od_file = def->df_file;
124 OutDef.od_line = def->df_line;
125 OutDef.od_type = (type->tp_fund == FUNCTION ? type->tp_up : type);
126 OutDef.od_valreturned = NORETURN;
132 /* It was assumed we were parsing a function definition.
133 * There was no compound statement following, so actually it was a
134 * declaration. This function updates the class.
136 OutDef.od_class = (sc == STATIC ? XXDF : EFDC);
139 set_od_valreturned(n)
141 OutDef.od_valreturned = n;
152 od.od_name = idf->id_text;
153 od.od_file = idf->id_def->df_file;
154 od.od_line = idf->id_def->df_line;
155 od.od_type = idf->id_def->df_type->tp_up;
157 /* The other fields are not used for this class. */
162 /* Make a list of 'struct argument's containing the types of the formal
163 * parameters of the function definition just parsed.
165 register struct stack_entry *se = stack_level_of(L_FORMAL1)->sl_entry;
166 register struct argument **hook = &OutDef.od_arg;
167 register int nrargs = 0;
170 register struct type *type = se->se_idf->id_def->df_type;
171 register struct argument *arg = new_argument();
173 /* Do the conversions on the formals that could not be
174 done in declare_idf().
175 It is, unfortunately, impossible not to do them,
176 since the corresponding actuals will have been
177 converted to generate proper code and we do not
178 want to duplicate the whole of expression handling
181 switch (type->tp_fund) {
184 type = (type->tp_unsigned ? uint_type : int_type);
191 if (f_FORMAT && nrargs == f_FORMATn) {
193 && ( type->tp_fund != POINTER
194 || type->tp_up->tp_fund != CHAR
197 warning("format parameter %d is not pointer to char",
200 arg->ar_type = string_type;
201 arg->ar_class = ArgString;
202 arg->CAS_VALUE = f_FORMAT;
203 arg->CAS_LEN = strlen(f_FORMAT);
208 arg->ar_class = ArgFormal;
218 /* f_FORMAT has not been consumed, perhaps due to
219 a varargs-like construction; add erroneous ArgFormals
220 until f_FORMATn, then an ArgString, if necessary.
223 warning("FORMAT%d function has only %d argument%s",
224 f_FORMATn, nrargs, nrargs == 1 ? "" : "s"
228 while (nrargs < f_FORMATn) {
229 register struct argument *arg = new_argument();
231 arg->ar_type = error_type;
232 arg->ar_class = ArgFormal;
237 if (nrargs == f_FORMATn) {
238 register struct argument *arg = new_argument();
240 arg->ar_type = string_type;
241 arg->ar_class = ArgString;
242 arg->CAS_VALUE = f_FORMAT;
243 arg->CAS_LEN = strlen(f_FORMAT);
249 /* life is full of duplicated code; this is no good */
252 if (f_VARARGSn > nrargs) {
253 warning("VARARGS%d function has only %d argument%s",
254 f_VARARGSn, nrargs, nrargs == 1 ? "" : "s"
258 OutDef.od_nrargs = nrargs;
264 /* Output the usage-definition of the variable described by idf.
266 OutDef.od_name = idf->id_text;
267 OutDef.od_statnr = (idf->id_def->df_sc == STATIC ? stat_number : 0);
268 OutDef.od_class = VU;
269 OutDef.od_file = FileName;
270 OutDef.od_line = LineNumber;
271 OutDef.od_type = idf->id_def->df_type;
282 output_def(&OutCall);
289 /* As the types are output the 'struct argument's are removed, because they
290 * are then not needed anymore.
292 if (od->od_class == XXDF || !od->od_name || od->od_name[0] == '#')
296 switch (od->od_class) {
304 /* remove 'struct argument's */
306 register struct argument *tmp = od->od_arg;
307 od->od_arg = od->od_arg->next;
315 printf("%s:%d:%c", od->od_name, od->od_statnr, od->od_class);
316 switch (od->od_class) {
320 if (f_VARARGSn != -1) {
321 printf(":%d", -1 - f_VARARGSn);
322 outargs(od->od_arg, f_VARARGSn);
325 printf(":%d", od->od_nrargs);
326 outargs(od->od_arg, od->od_nrargs);
329 printf(":%d", od->od_valreturned);
332 printf(":%d", od->od_nrargs);
333 outargs(od->od_arg, od->od_nrargs);
335 printf(":%d", od->od_valused);
350 outargtype(od->od_type);
351 printf(":%u:%s\n", od->od_line, od->od_file);
356 struct argument *arg;
358 /* Output the n arguments in the argument list and remove them */
360 register struct argument *tmp;
369 /* remove the remaining entries */
379 struct argument *arg;
382 switch (arg->ar_class) {
384 if (arg->CAA_VALUE >= 0) {
385 /* constant non-negative actual parameter */
388 outargtype(arg->ar_type);
397 outargtype(arg->ar_type);
398 if (arg->ar_type->tp_fund == FUNCTION) {
399 /* UGLY PATCH !!! ??? */
400 /* function names as operands are sometimes
401 FUNCTION and sometimes POINTER to FUNCTION,
402 depending on opaque circumstances. E.g., in
404 the first main is PtF and the second is F.
418 struct argument *arg;
423 bts2str(arg->CAS_VALUE, arg->CAS_LEN, buff);
424 for (p = &buff[0]; *p; p++) {
425 if (*p == '"' || *p == ':')
428 printf("\"%s\"", buff);
435 switch (tp->tp_fund) {
437 outargtype(tp->tp_up);
442 outargtype(tp->tp_up);
443 printf("*"); /* compatible with [] */
447 outargtype(tp->tp_up);
454 /* watch out for anonymous identifiers; the count field does
455 not have to be the same for all compilation units.
456 Remove it, so that pass 2 does not see it. The only
457 problem with this is that pass2 will not see a difference
458 between two non-tagged types declared on the same line.
460 printf("%s ", symbol2str(tp->tp_fund));
461 if (is_anon_idf(tp->tp_idf)) {
462 /* skip the #<num>, replace it by '#anonymous id' */
463 printf("#anonymous id%s", strindex(tp->tp_idf->id_text, ' '));
465 else printf(tp->tp_idf->id_text);
478 printf("%s", symbol2str(tp->tp_fund));
488 implicit_func_decl(idf, file, line)
497 od.od_name = idf->id_text;
500 od.od_type = idf->id_def->df_type->tp_up;
502 /* The other fields are not used for this class. */
504 #endif /* IMPLICIT */
506 fill_outcall(ex, used)
510 register struct idf *idf = ex->OP_LEFT->VL_IDF;
511 register struct def *def = idf->id_def;
514 if (def->df_sc == IMPLICIT && !idf->id_def->df_used) {
515 /* IFDC, first time */
516 implicit_func_decl(idf, ex->ex_file, ex->ex_line);
518 #endif /* IMPLICIT */
520 OutCall.od_type = def->df_type->tp_up;
521 OutCall.od_statnr = (def->df_sc == STATIC ? stat_number : 0);
522 OutCall.od_class = FC;
523 OutCall.od_name = idf->id_text;
524 OutCall.od_file = ex->ex_file;
525 OutCall.od_line = ex->ex_line;
526 OutCall.od_arg = (struct argument *)0;
527 OutCall.od_nrargs = 0;
529 if ((ex = ex->OP_RIGHT) != 0) {
530 /* function call with arguments */
531 /* store types of argument expressions in 'struct argument's */
532 while (ex->ex_class == Oper && ex->OP_OPER == PARCOMMA) {
533 add_expr_arg(ex->OP_RIGHT);
538 OutCall.od_valused = used; /* USED, IGNORED or VOIDED */
545 register struct argument *arg;
547 arg = new_argument();
548 arg->ar_type = e->ex_type;
550 arg->ar_class = ArgConst;
551 arg->CAA_VALUE = e->VL_VALUE;
553 else if ( e->ex_type == string_type
554 && e->ex_class == Value
555 && e->VL_CLASS == Label
557 /* it may be a string; let's look it up */
558 register struct string_cst *sc = str_list;
561 if (sc->sc_dlb == e->VL_LBL)
566 /* it was a string */
567 arg->ar_class = ArgString;
568 arg->CAS_VALUE = sc->sc_value;
569 arg->CAS_LEN = sc->sc_len - 1; /* included the \0 */
572 arg->ar_class = ArgExpr;
576 arg->ar_class = ArgExpr;
578 arg->next = OutCall.od_arg;
579 OutCall.od_arg = arg;