l_outdef.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583
  1. /*
  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".
  4. */
  5. /* $Id$ */
  6. /* Lint outdef construction */
  7. #include "lint.h"
  8. #ifdef LINT
  9. #include <alloc.h>
  10. #include "interface.h"
  11. #ifdef ANSI
  12. #include <flt_arith.h>
  13. #endif /* ANSI */
  14. #include "arith.h"
  15. #include "assert.h"
  16. #include "type.h"
  17. #include "declar.h"
  18. #include "decspecs.h"
  19. #include "LLlex.h"
  20. #include "Lpars.h"
  21. #include "stack.h"
  22. #include "def.h"
  23. #include "struct.h"
  24. #include "field.h"
  25. #include "idf.h"
  26. #include "level.h"
  27. #include "label.h"
  28. #include "code.h"
  29. #include "expr.h"
  30. #include "l_lint.h"
  31. #include "l_comment.h"
  32. #include "l_outdef.h"
  33. #include "l_class.h"
  34. extern char *bts2str();
  35. extern char *symbol2str();
  36. extern char *strchr();
  37. int stat_number = 9999; /* static scope number */
  38. struct outdef OutDef;
  39. PRIVATE struct outdef OutCall;
  40. PRIVATE local_EFDC();
  41. PRIVATE output_def();
  42. PRIVATE outargs();
  43. PRIVATE outarg();
  44. PRIVATE outargstring();
  45. PRIVATE outargtype();
  46. PRIVATE add_expr_arg();
  47. lint_declare_idf(idf, sc)
  48. struct idf *idf;
  49. int sc;
  50. {
  51. register struct def *def = idf->id_def;
  52. register int is_function = def->df_type->tp_fund == FUNCTION;
  53. if (level == L_GLOBAL) {
  54. lint_ext_def(idf, sc);
  55. if (is_function)
  56. def2decl(sc);
  57. if (sc != TYPEDEF)
  58. outdef();
  59. }
  60. else
  61. if (level >= L_LOCAL && sc != STATIC && is_function) {
  62. local_EFDC(idf);
  63. }
  64. }
  65. lint_non_function_decl(ds, dc)
  66. struct decspecs *ds;
  67. struct declarator *dc;
  68. {
  69. register struct def *def = dc->dc_idf->id_def;
  70. register int is_function = def->df_type->tp_fund == FUNCTION;
  71. if (is_function)
  72. def2decl(ds->ds_sc);
  73. if (def->df_sc != TYPEDEF)
  74. outdef();
  75. }
  76. lint_ext_def(idf, sc)
  77. struct idf *idf;
  78. {
  79. /* At this place the following fields of the output definition can be
  80. * filled:
  81. * name, stat_number, class, file, line, type.
  82. * For variable definitions and declarations this will be all.
  83. * For functions the fields nrargs and argtps are filled after parsing
  84. * the arguments.
  85. * The returns-field is known at the end of the function definition.
  86. * sc indicates the storage class defined by the declaration specifier.
  87. */
  88. register struct def *def = idf->id_def;
  89. register struct type *type = def->df_type;
  90. OutDef.od_name = idf->id_text;
  91. OutDef.od_statnr = (sc == STATIC ? stat_number : 0);
  92. switch (type->tp_fund) {
  93. case ERRONEOUS:
  94. OutDef.od_class = XXDF;
  95. break;
  96. case FUNCTION:
  97. /* For the moment assume it will be a definition.
  98. * If no compound_statement follows, it is a declaration,
  99. * in which case the class will be adjusted by def2decl().
  100. */
  101. OutDef.od_class = (sc == STATIC ? SFDF : EFDF);
  102. break;
  103. default: /* a variable */
  104. OutDef.od_class =
  105. sc == EXTERN ? EVDC :
  106. sc == STATIC ? SVDF : EVDF;
  107. break;
  108. }
  109. OutDef.od_file = def->df_file;
  110. OutDef.od_line = def->df_line;
  111. OutDef.od_type = (type->tp_fund == FUNCTION ? type->tp_up : type);
  112. OutDef.od_valreturned = NORETURN;
  113. }
  114. def2decl(sc)
  115. int sc;
  116. {
  117. /* It was assumed we were parsing a function definition.
  118. * There was no compound statement following, so actually it was a
  119. * declaration. This function updates the class.
  120. */
  121. OutDef.od_class = (sc == STATIC ? XXDF : EFDC);
  122. }
  123. set_od_valreturned(n)
  124. {
  125. OutDef.od_valreturned = n;
  126. }
  127. PRIVATE
  128. local_EFDC(idf)
  129. struct idf *idf;
  130. {
  131. struct outdef od;
  132. od.od_class = EFDC;
  133. od.od_statnr = 0;
  134. od.od_name = idf->id_text;
  135. od.od_file = idf->id_def->df_file;
  136. od.od_line = idf->id_def->df_line;
  137. od.od_type = idf->id_def->df_type->tp_up;
  138. output_def(&od);
  139. /* The other fields are not used for this class. */
  140. }
  141. lint_formals()
  142. {
  143. /* Make a list of 'struct argument's containing the types of the formal
  144. * parameters of the function definition just parsed.
  145. */
  146. register struct stack_entry *se = stack_level_of(L_FORMAL1)->sl_entry;
  147. register struct argument **hook = &OutDef.od_arg;
  148. register int nrargs = 0;
  149. while (se) {
  150. register struct type *type = se->se_idf->id_def->df_type;
  151. register struct argument *arg = new_argument();
  152. /* Do the conversions on the formals that could not be
  153. done in declare_idf().
  154. It is, unfortunately, impossible not to do them,
  155. since the corresponding actuals will have been
  156. converted to generate proper code and we do not
  157. want to duplicate the whole of expression handling
  158. for lint.
  159. */
  160. switch (type->tp_fund) {
  161. case CHAR:
  162. case SHORT:
  163. type = (type->tp_unsigned ? uint_type : int_type);
  164. break;
  165. case FLOAT:
  166. type = double_type;
  167. break;
  168. }
  169. if (f_FORMAT && nrargs == f_FORMATn) {
  170. if ( !f_FORMATvar
  171. && ( type->tp_fund != POINTER
  172. || type->tp_up->tp_fund != CHAR
  173. )
  174. ) {
  175. warning("format parameter %d is not pointer to char",
  176. nrargs);
  177. }
  178. arg->ar_type = string_type;
  179. arg->ar_class = ArgString;
  180. arg->CAS_VALUE = f_FORMAT;
  181. arg->CAS_LEN = strlen(f_FORMAT);
  182. f_FORMAT = 0;
  183. }
  184. else {
  185. arg->ar_type = type;
  186. arg->ar_class = ArgFormal;
  187. }
  188. *hook = arg;
  189. hook = &arg->next;
  190. nrargs++;
  191. se = se->next;
  192. }
  193. if (f_FORMAT) {
  194. /* f_FORMAT has not been consumed, perhaps due to
  195. a varargs-like construction; add erroneous ArgFormals
  196. until f_FORMATn, then an ArgString, if necessary.
  197. */
  198. if (!f_FORMATvar) {
  199. warning("FORMAT%d function has only %d argument%s",
  200. f_FORMATn, nrargs, nrargs == 1 ? "" : "s"
  201. );
  202. }
  203. while (nrargs < f_FORMATn) {
  204. register struct argument *arg = new_argument();
  205. arg->ar_type = error_type;
  206. arg->ar_class = ArgFormal;
  207. *hook = arg;
  208. hook = &arg->next;
  209. nrargs++;
  210. }
  211. if (nrargs == f_FORMATn) {
  212. register struct argument *arg = new_argument();
  213. arg->ar_type = string_type;
  214. arg->ar_class = ArgString;
  215. arg->CAS_VALUE = f_FORMAT;
  216. arg->CAS_LEN = strlen(f_FORMAT);
  217. f_FORMAT = 0;
  218. *hook = arg;
  219. hook = &arg->next;
  220. nrargs++;
  221. }
  222. /* life is full of duplicated code; this is no good */
  223. }
  224. if (f_VARARGSn > nrargs) {
  225. warning("VARARGS%d function has only %d argument%s",
  226. f_VARARGSn, nrargs, nrargs == 1 ? "" : "s"
  227. );
  228. f_VARARGSn = nrargs;
  229. }
  230. OutDef.od_nrargs = nrargs;
  231. }
  232. output_use(idf)
  233. struct idf *idf;
  234. {
  235. /* Output the usage-definition of the variable described by idf.
  236. */
  237. OutDef.od_name = idf->id_text;
  238. OutDef.od_statnr = (idf->id_def->df_sc == STATIC ? stat_number : 0);
  239. OutDef.od_class = VU;
  240. OutDef.od_file = FileName;
  241. OutDef.od_line = LineNumber;
  242. OutDef.od_type = idf->id_def->df_type;
  243. outdef();
  244. }
  245. outdef()
  246. {
  247. output_def(&OutDef);
  248. }
  249. outcall()
  250. {
  251. output_def(&OutCall);
  252. }
  253. PRIVATE
  254. output_def(od)
  255. struct outdef *od;
  256. {
  257. /* As the types are output the 'struct argument's are removed, because they
  258. * are then not needed anymore.
  259. */
  260. if (od->od_class == XXDF || !od->od_name || od->od_name[0] == '#')
  261. return;
  262. if (LINTLIB) {
  263. switch (od->od_class) {
  264. case EFDF:
  265. od->od_class = LFDF;
  266. break;
  267. case EVDF:
  268. od->od_class = LVDF;
  269. break;
  270. case SFDF:
  271. /* remove 'struct argument's */
  272. while (od->od_arg) {
  273. register struct argument *tmp = od->od_arg;
  274. od->od_arg = od->od_arg->next;
  275. free_argument(tmp);
  276. }
  277. return;
  278. default:
  279. return;
  280. }
  281. }
  282. printf("%s:%d:%c", od->od_name, od->od_statnr, od->od_class);
  283. switch (od->od_class) {
  284. case EFDF:
  285. case SFDF:
  286. case LFDF:
  287. if (f_VARARGSn != -1) {
  288. printf(":%d", -1 - f_VARARGSn);
  289. outargs(od->od_arg, f_VARARGSn);
  290. }
  291. else {
  292. printf(":%d", od->od_nrargs);
  293. outargs(od->od_arg, od->od_nrargs);
  294. }
  295. od->od_arg = 0;
  296. printf(":%d", od->od_valreturned);
  297. break;
  298. case FC:
  299. printf(":%d", od->od_nrargs);
  300. outargs(od->od_arg, od->od_nrargs);
  301. od->od_arg = 0;
  302. printf(":%d", od->od_valused);
  303. break;
  304. case EVDF:
  305. case SVDF:
  306. case LVDF:
  307. case EFDC:
  308. case EVDC:
  309. case IFDC:
  310. case VU:
  311. break;
  312. default:
  313. NOTREACHED();
  314. /*NOTREACHED*/
  315. }
  316. printf(":");
  317. outargtype(od->od_type);
  318. printf(":%u:%s\n", od->od_line, od->od_file);
  319. }
  320. PRIVATE
  321. outargs(arg, n)
  322. struct argument *arg;
  323. {
  324. /* Output the n arguments in the argument list and remove them */
  325. register struct argument *tmp;
  326. while (n--) {
  327. ASSERT(arg);
  328. outarg(arg);
  329. tmp = arg;
  330. arg = arg->next;
  331. free_argument(tmp);
  332. }
  333. /* remove the remaining entries */
  334. while (arg) {
  335. tmp = arg;
  336. arg = arg->next;
  337. free_argument(tmp);
  338. }
  339. }
  340. PRIVATE
  341. outarg(arg)
  342. struct argument *arg;
  343. {
  344. printf(":");
  345. switch (arg->ar_class) {
  346. case ArgConst:
  347. if (arg->CAA_VALUE >= 0) {
  348. /* constant non-negative actual parameter */
  349. printf("+");
  350. }
  351. outargtype(arg->ar_type);
  352. break;
  353. case ArgString:
  354. outargstring(arg);
  355. break;
  356. case ArgFormal:
  357. case ArgExpr:
  358. outargtype(arg->ar_type);
  359. if (arg->ar_type->tp_fund == FUNCTION) {
  360. /* UGLY PATCH !!! ??? */
  361. /* function names as operands are sometimes
  362. FUNCTION and sometimes POINTER to FUNCTION,
  363. depending on opaque circumstances. E.g., in
  364. f(main, main);
  365. the first main is PtF and the second is F.
  366. */
  367. printf("*");
  368. }
  369. break;
  370. default:
  371. NOTREACHED();
  372. /*NOTREACHED*/
  373. }
  374. }
  375. PRIVATE
  376. outargstring(arg)
  377. struct argument *arg;
  378. {
  379. char buff[1000];
  380. register char *p;
  381. bts2str(arg->CAS_VALUE, arg->CAS_LEN, buff);
  382. for (p = &buff[0]; *p; p++) {
  383. if (*p == '"' || *p == ':')
  384. *p = ' ';
  385. }
  386. printf("\"%s\"", buff);
  387. }
  388. PRIVATE
  389. outargtype(tp)
  390. struct type *tp;
  391. {
  392. switch (tp->tp_fund) {
  393. case POINTER:
  394. outargtype(tp->tp_up);
  395. printf("*");
  396. break;
  397. case ARRAY:
  398. outargtype(tp->tp_up);
  399. printf("*"); /* compatible with [] */
  400. break;
  401. case FUNCTION:
  402. outargtype(tp->tp_up);
  403. printf("()");
  404. break;
  405. case STRUCT:
  406. case UNION:
  407. case ENUM:
  408. /* watch out for anonymous identifiers; the count field does
  409. not have to be the same for all compilation units.
  410. Remove it, so that pass 2 does not see it. The only
  411. problem with this is that pass2 will not see a difference
  412. between two non-tagged types declared on the same line.
  413. */
  414. printf("%s ", symbol2str(tp->tp_fund));
  415. if (is_anon_idf(tp->tp_idf)) {
  416. /* skip the #<num>, replace it by '#anonymous id' */
  417. printf("#anonymous id%s", strchr(tp->tp_idf->id_text, ' '));
  418. }
  419. else printf(tp->tp_idf->id_text);
  420. break;
  421. case CHAR:
  422. case INT:
  423. case SHORT:
  424. case LONG:
  425. case FLOAT:
  426. case DOUBLE:
  427. case VOID:
  428. case ERRONEOUS:
  429. if (tp->tp_unsigned)
  430. printf("unsigned ");
  431. printf("%s", symbol2str(tp->tp_fund));
  432. break;
  433. default:
  434. NOTREACHED();
  435. /*NOTREACHED*/
  436. }
  437. }
  438. #ifdef IMPLICIT
  439. PRIVATE
  440. implicit_func_decl(idf, file, line)
  441. struct idf *idf;
  442. char *file;
  443. unsigned int line;
  444. {
  445. struct outdef od;
  446. od.od_class = IFDC;
  447. od.od_statnr = 0;
  448. od.od_name = idf->id_text;
  449. od.od_file = file;
  450. od.od_line = line;
  451. od.od_type = idf->id_def->df_type->tp_up;
  452. output_def(&od);
  453. /* The other fields are not used for this class. */
  454. }
  455. #endif /* IMPLICIT */
  456. fill_outcall(ex, used)
  457. struct expr *ex;
  458. int used;
  459. {
  460. register struct idf *idf = ex->OP_LEFT->VL_IDF;
  461. register struct def *def = idf->id_def;
  462. #ifdef IMPLICIT
  463. if (def->df_sc == IMPLICIT && !idf->id_def->df_used) {
  464. /* IFDC, first time */
  465. implicit_func_decl(idf, ex->ex_file, ex->ex_line);
  466. }
  467. #endif /* IMPLICIT */
  468. OutCall.od_type = def->df_type->tp_up;
  469. OutCall.od_statnr = (def->df_sc == STATIC ? stat_number : 0);
  470. OutCall.od_class = FC;
  471. OutCall.od_name = idf->id_text;
  472. OutCall.od_file = ex->ex_file;
  473. OutCall.od_line = ex->ex_line;
  474. OutCall.od_arg = (struct argument *)0;
  475. OutCall.od_nrargs = 0;
  476. if ((ex = ex->OP_RIGHT) != 0) {
  477. /* function call with arguments */
  478. /* store types of argument expressions in 'struct argument's */
  479. while (ex->ex_class == Oper && ex->OP_OPER == PARCOMMA) {
  480. add_expr_arg(ex->OP_RIGHT);
  481. ex = ex->OP_LEFT;
  482. }
  483. add_expr_arg(ex);
  484. }
  485. OutCall.od_valused = used; /* USED, IGNORED or VOIDED */
  486. }
  487. PRIVATE
  488. add_expr_arg(e)
  489. struct expr *e;
  490. {
  491. register struct argument *arg;
  492. arg = new_argument();
  493. arg->ar_type = e->ex_type;
  494. if (is_cp_cst(e)) {
  495. arg->ar_class = ArgConst;
  496. arg->CAA_VALUE = e->VL_VALUE;
  497. }
  498. else if ( e->ex_type == string_type
  499. && e->ex_class == Value
  500. && e->VL_CLASS == Label
  501. ) {
  502. /* it may be a string; let's look it up */
  503. register struct string_cst *sc = str_list;
  504. while (sc) {
  505. if (sc->sc_dlb == e->VL_LBL)
  506. break;
  507. sc = sc->next;
  508. }
  509. if (sc) {
  510. /* it was a string */
  511. arg->ar_class = ArgString;
  512. arg->CAS_VALUE = sc->sc_value;
  513. arg->CAS_LEN = sc->sc_len - 1; /* included the \0 */
  514. }
  515. else {
  516. arg->ar_class = ArgExpr;
  517. }
  518. }
  519. else {
  520. arg->ar_class = ArgExpr;
  521. }
  522. arg->next = OutCall.od_arg;
  523. OutCall.od_arg = arg;
  524. OutCall.od_nrargs++;
  525. }
  526. #endif /* LINT */