l_outdef.c 13 KB

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