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 1.7 1994/06/27 08:01:04 ceriel Exp $ */
6 /* Lint outdef construction */
13 #include "interface.h"
15 #include <flt_arith.h>
35 #include "l_comment.h"
39 extern char *bts2str();
40 extern char *symbol2str();
41 extern char *strindex();
43 int stat_number = 9999; /* static scope number */
46 PRIVATE struct outdef OutCall;
52 PRIVATE outargstring();
54 PRIVATE add_expr_arg();
57 lint_declare_idf(idf, sc)
61 register struct def *def = idf->id_def;
62 register int is_function = def->df_type->tp_fund == FUNCTION;
64 if (level == L_GLOBAL) {
65 lint_ext_def(idf, sc);
72 if (level >= L_LOCAL && sc != STATIC && is_function) {
77 lint_non_function_decl(ds, dc)
79 struct declarator *dc;
81 register struct def *def = dc->dc_idf->id_def;
82 register int is_function = def->df_type->tp_fund == FUNCTION;
86 if (def->df_sc != TYPEDEF)
93 /* At this place the following fields of the output definition can be
95 * od_name, od_statnr, od_class, od_file, od_line, od_type.
96 * For variable definitions and declarations this will be all.
97 * For functions the fields od_nrargs and od_arg are filled after parsing
99 * The od_valreturned field is known at the end of the function definition.
100 * sc indicates the storage class defined by the declaration specifier.
102 register struct def *def = idf->id_def;
103 register struct type *type = def->df_type;
105 OutDef.od_name = idf->id_text;
106 OutDef.od_statnr = (sc == STATIC ? stat_number : 0);
108 switch (type->tp_fund) {
110 OutDef.od_class = XXDF;
113 /* For the moment assume it will be a definition.
114 * If no compound_statement follows, it is a declaration,
115 * in which case the class will be adjusted by def2decl().
117 OutDef.od_class = (sc == STATIC ? SFDF : EFDF);
119 default: /* a variable */
121 sc == EXTERN ? EVDC :
122 sc == STATIC ? SVDF : EVDF;
125 OutDef.od_file = def->df_file;
126 OutDef.od_line = def->df_line;
127 OutDef.od_type = (type->tp_fund == FUNCTION ? type->tp_up : type);
128 OutDef.od_valreturned = NORETURN;
135 /* It was assumed we were parsing a function definition.
136 * There was no compound statement following, so actually it was a
137 * declaration. This function updates the class.
139 OutDef.od_class = (sc == STATIC ? XXDF : EFDC);
142 set_od_valreturned(n)
144 OutDef.od_valreturned = n;
155 od.od_name = idf->id_text;
156 od.od_file = idf->id_def->df_file;
157 od.od_line = idf->id_def->df_line;
158 od.od_type = idf->id_def->df_type->tp_up;
160 /* The other fields are not used for this class. */
165 /* Make a list of 'struct argument's containing the types of the formal
166 * parameters of the function definition just parsed.
168 register struct stack_entry *se = stack_level_of(L_FORMAL1)->sl_entry;
169 register struct argument **hook = &OutDef.od_arg;
170 register int nrargs = 0;
173 register struct type *type = se->se_idf->id_def->df_type;
174 register struct argument *arg = new_argument();
176 if (f_FORMAT && nrargs == f_FORMATn) {
178 && ( type->tp_fund != POINTER
179 || type->tp_up->tp_fund != CHAR
182 warning("format parameter %d is not pointer to char",
185 arg->ar_type = string_type;
186 arg->ar_class = ArgString;
187 arg->CAS_VALUE = f_FORMAT;
188 arg->CAS_LEN = strlen(f_FORMAT);
193 arg->ar_class = ArgFormal;
203 /* f_FORMAT has not been consumed, perhaps due to
204 a varargs-like construction; add erroneous ArgFormals
205 until f_FORMATn, then an ArgString, if necessary.
208 warning("FORMAT%d function has only %d argument%s",
209 f_FORMATn, nrargs, nrargs == 1 ? "" : "s"
213 while (nrargs < f_FORMATn) {
214 register struct argument *arg = new_argument();
216 arg->ar_type = error_type;
217 arg->ar_class = ArgFormal;
222 if (nrargs == f_FORMATn) {
223 register struct argument *arg = new_argument();
225 arg->ar_type = string_type;
226 arg->ar_class = ArgString;
227 arg->CAS_VALUE = f_FORMAT;
228 arg->CAS_LEN = strlen(f_FORMAT);
234 /* life is full of duplicated code; this is no good */
237 if (f_VARARGSn > nrargs) {
238 warning("VARARGS%d function has only %d argument%s",
239 f_VARARGSn, nrargs, nrargs == 1 ? "" : "s"
243 OutDef.od_nrargs = nrargs;
246 output_proto(idf, def)
250 /* fund == FUNCTION && sc != STATIC */
251 register struct proto *pl = def->df_type->tp_proto;
252 register int nrargs = 0;
256 OutDef.od_name = idf->id_text;
257 OutDef.od_statnr = 0;
258 OutDef.od_class = PFDF;
259 OutDef.od_file = def->df_file;
260 OutDef.od_line = def->df_line;
261 OutDef.od_type = def->df_type->tp_up;
262 OutDef.od_valreturned = NORETURN;/*???*/
265 register struct type *type = pl->pl_type;
266 register struct argument *arg = new_argument();
270 arg->ar_class = ArgFormal;
273 arg->ar_class = ArgEllipsis;
275 arg->next = OutDef.od_arg;
282 OutDef.od_nrargs = nrargs;
289 /* Output the usage-definition of the variable described by idf.
291 OutDef.od_name = idf->id_text;
292 OutDef.od_statnr = (idf->id_def->df_sc == STATIC ? stat_number : 0);
293 OutDef.od_class = VU;
294 OutDef.od_file = FileName;
295 OutDef.od_line = LineNumber;
296 OutDef.od_type = idf->id_def->df_type;
307 output_def(&OutCall);
314 /* As the types are output the 'struct argument's are freed, because they
315 * are then not needed anymore.
317 if (od->od_class == XXDF || !od->od_name || od->od_name[0] == '#')
321 switch (od->od_class) {
329 /* free the 'struct argument's */
331 register struct argument *tmp = od->od_arg;
332 od->od_arg = od->od_arg->next;
340 printf("%s:%d:%c", od->od_name, od->od_statnr, od->od_class);
341 switch (od->od_class) {
346 if (f_VARARGSn != -1) {
347 printf(":%d", -1 - f_VARARGSn);
348 outargs(od->od_arg, f_VARARGSn);
351 printf(":%d", od->od_nrargs);
352 outargs(od->od_arg, od->od_nrargs);
355 printf(":%d", od->od_valreturned);
358 printf(":%d", od->od_nrargs);
359 outargs(od->od_arg, od->od_nrargs);
361 printf(":%d", od->od_valused);
376 outargtype(od->od_type);
377 printf(":%u:%s\n", od->od_line, od->od_file);
382 struct argument *arg;
384 /* Output the n arguments in the argument list and remove them */
386 register struct argument *tmp;
395 /* remove the remaining entries */
405 struct argument *arg;
408 switch (arg->ar_class) {
410 if (arg->CAA_VALUE >= 0) {
411 /* constant non-negative actual parameter */
414 outargtype(arg->ar_type);
423 outargtype(arg->ar_type);
424 if (arg->ar_type->tp_fund == FUNCTION) {
425 /* UGLY PATCH !!! ??? */
426 /* function names as operands are sometimes
427 FUNCTION and sometimes POINTER to FUNCTION,
428 depending on opaque circumstances. E.g., in
430 the first main is PtF and the second is F.
437 printf("."); /* one is enough for computers */
448 struct argument *arg;
453 bts2str(arg->CAS_VALUE, arg->CAS_LEN, buff);
454 for (p = &buff[0]; *p; p++) {
455 if (*p == '"' || *p == ':')
458 printf("\"%s\"", buff);
465 switch (tp->tp_fund) {
467 outargtype(tp->tp_up);
472 outargtype(tp->tp_up);
473 printf("*"); /* compatible with [] */
477 outargtype(tp->tp_up);
484 /* watch out for anonymous identifiers; the count field does
485 not have to be the same for all compilation units.
486 Remove it, so that pass 2 does not see it. The only
487 problem with this is that pass2 will not see a difference
488 between two non-tagged types declared on the same line.
490 printf("%s ", symbol2str(tp->tp_fund));
491 if (is_anon_idf(tp->tp_idf)) {
492 /* skip the #<num>, replace it by '#anonymous id' */
493 printf("#anonymous id%s",
494 strindex(tp->tp_idf->id_text, ' ')
498 printf(tp->tp_idf->id_text);
512 if (tp->tp_unsigned) {
515 printf("%s", symbol2str(tp->tp_fund));
525 implicit_func_decl(idf, file, line)
534 od.od_name = idf->id_text;
537 od.od_type = idf->id_def->df_type->tp_up;
539 /* The other fields are not used for this class. */
541 #endif /* IMPLICIT */
543 fill_outcall(ex, used)
547 register struct idf *idf = ex->OP_LEFT->VL_IDF;
548 register struct def *def = idf->id_def;
551 if (def->df_sc == IMPLICIT && !idf->id_def->df_used) {
552 /* IFDC, first time */
553 implicit_func_decl(idf, ex->ex_file, ex->ex_line);
555 #endif /* IMPLICIT */
557 OutCall.od_type = def->df_type->tp_up;
558 OutCall.od_statnr = (def->df_sc == STATIC ? stat_number : 0);
559 OutCall.od_class = FC;
560 OutCall.od_name = idf->id_text;
561 OutCall.od_file = ex->ex_file;
562 OutCall.od_line = ex->ex_line;
563 OutCall.od_arg = (struct argument *)0;
564 OutCall.od_nrargs = 0;
566 if ((ex = ex->OP_RIGHT) != 0) {
567 /* function call with arguments: */
568 /* store types of argument expressions in 'struct argument's */
569 while (ex->ex_class == Oper && ex->OP_OPER == PARCOMMA) {
570 add_expr_arg(ex->OP_RIGHT);
575 OutCall.od_valused = used; /* USED, IGNORED or VOIDED */
582 register struct argument *arg;
584 arg = new_argument();
585 arg->ar_type = e->ex_type;
587 arg->ar_class = ArgConst;
588 arg->CAA_VALUE = e->VL_VALUE;
590 else if ( e->ex_type == string_type
591 && e->ex_class == Value
592 && e->VL_CLASS == Label
594 /* it may be a string; let's look it up */
595 register struct string_cst *sc = str_list;
598 if (sc->sc_dlb == e->VL_LBL)
603 /* it was a string */
604 arg->ar_class = ArgString;
605 arg->CAS_VALUE = sc->sc_value;
606 arg->CAS_LEN = sc->sc_len - 1; /* included the \0 */
609 arg->ar_class = ArgExpr;
613 arg->ar_class = ArgExpr;
615 arg->next = OutCall.od_arg;
616 OutCall.od_arg = arg;