expr.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479
  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. /* EXPRESSION TREE HANDLING */
  7. #include <stdlib.h>
  8. #include "lint.h"
  9. #include "debug.h"
  10. #include "assert.h"
  11. #include "botch_free.h"
  12. #include <alloc.h>
  13. #include "idf.h"
  14. #include <flt_arith.h>
  15. #include "arith.h"
  16. #include "def.h"
  17. #include "type.h"
  18. #include "label.h"
  19. #include "expr.h"
  20. #include "LLlex.h"
  21. #include "Lpars.h"
  22. #include "decspecs.h"
  23. #include "declar.h"
  24. #include "sizes.h"
  25. #include "level.h"
  26. #include "use_tmp.h"
  27. #include "cstoper.h"
  28. #include "idf_loc.h"
  29. #include "expr_loc.h"
  30. #include "error.h"
  31. #include <symbol2str.h>
  32. extern char options[];
  33. extern int InSizeof;
  34. int rank_of(int oper)
  35. {
  36. /* The rank of the operator oper is returned.
  37. */
  38. switch (oper) {
  39. default:
  40. return 0; /* INT2INT etc. */
  41. case '[':
  42. case '(':
  43. case '.':
  44. case ARROW:
  45. case PARCOMMA:
  46. return 1;
  47. case '!':
  48. case PLUSPLUS:
  49. case MINMIN:
  50. case CAST:
  51. case SIZEOF:
  52. case ADDRESSOF:
  53. return 2; /* monadic */
  54. case '*':
  55. case '/':
  56. case '%':
  57. return 3;
  58. case '+':
  59. case '-':
  60. return 4;
  61. case LEFT:
  62. case RIGHT:
  63. return 5;
  64. case '<':
  65. case '>':
  66. case LESSEQ:
  67. case GREATEREQ:
  68. return 6;
  69. case EQUAL:
  70. case NOTEQUAL:
  71. return 7;
  72. case '&':
  73. return 8;
  74. case '^':
  75. return 9;
  76. case '|':
  77. return 10;
  78. case AND:
  79. return 11;
  80. case OR:
  81. return 12;
  82. case '?':
  83. case ':':
  84. return 13;
  85. case '=':
  86. case PLUSAB:
  87. case MINAB:
  88. case TIMESAB:
  89. case DIVAB:
  90. case MODAB:
  91. case RIGHTAB:
  92. case LEFTAB:
  93. case ANDAB:
  94. case XORAB:
  95. case ORAB:
  96. return 14;
  97. case ',':
  98. return 15;
  99. }
  100. /*NOTREACHED*/
  101. }
  102. void dot2expr(struct expr **expp)
  103. {
  104. /* The token in dot is converted into an expression, a
  105. pointer to which is stored in *expp.
  106. */
  107. struct expr *ex = new_expr();
  108. *expp = ex;
  109. ex->ex_file = dot.tk_file;
  110. ex->ex_line = dot.tk_line;
  111. switch (DOT) {
  112. case IDENTIFIER:
  113. idf2expr(ex);
  114. break;
  115. case INTEGER:
  116. int2expr(ex);
  117. break;
  118. case FLOATING:
  119. float2expr(ex);
  120. break;
  121. default:
  122. crash("bad conversion to expression");
  123. /*NOTREACHED*/
  124. }
  125. }
  126. void idf2expr(struct expr *expr)
  127. {
  128. /* Dot contains an identifier which is turned into an
  129. expression.
  130. Note that this constitutes an applied occurrence of
  131. the identifier.
  132. */
  133. struct idf *idf = dot.tk_idf; /* != 0*/
  134. struct def *def = idf->id_def;
  135. if (def == 0) {
  136. if (AHEAD == '(') {
  137. /* function call, declare name implicitly (3.3.2.2) */
  138. if (!options['o'])
  139. warning("implicit declaration of function %s"
  140. , idf->id_text);
  141. add_def(idf, EXTERN, funint_type, level);
  142. } else {
  143. if (!is_anon_idf(idf))
  144. error("%s undefined", idf->id_text);
  145. /* declare idf anyway */
  146. add_def(idf, 0, error_type, level);
  147. }
  148. def = idf->id_def;
  149. }
  150. /* now def != 0 */
  151. #ifndef LINT
  152. if (!InSizeof) {
  153. if (! def->df_used) {
  154. #ifndef PREPEND_SCOPES
  155. code_scope(idf->id_text, def);
  156. #endif /* PREPEND_SCOPES */
  157. def->df_used = 1;
  158. }
  159. }
  160. #endif /* LINT */
  161. expr->ex_type = def->df_type;
  162. if (expr->ex_type == error_type) {
  163. expr->ex_flags |= EX_ERROR;
  164. }
  165. expr->ex_lvalue =
  166. ( def->df_type->tp_fund == FUNCTION ||
  167. def->df_type->tp_fund == ARRAY ||
  168. def->df_sc == ENUM
  169. ) ? 0 : 1;
  170. if (def->df_type->tp_typequal & TQ_CONST)
  171. expr->ex_flags |= EX_READONLY;
  172. if (def->df_type->tp_typequal & TQ_VOLATILE)
  173. expr->ex_flags |= EX_VOLATILE;
  174. expr->ex_class = Value;
  175. if (def->df_sc == ENUM) {
  176. expr->VL_CLASS = Const;
  177. expr->VL_VALUE = def->df_address;
  178. }
  179. #ifndef LINT
  180. else
  181. if (def->df_sc == STATIC && def->df_level >= L_LOCAL) {
  182. expr->VL_CLASS = Label;
  183. expr->VL_LBL = def->df_address;
  184. expr->VL_VALUE = (arith)0;
  185. }
  186. #endif /* LINT */
  187. else {
  188. expr->VL_CLASS = Name;
  189. expr->VL_IDF = idf;
  190. expr->VL_VALUE = (arith)0;
  191. }
  192. }
  193. void string2expr(struct expr **expp, char *str, int len)
  194. {
  195. /* The string in the argument is converted into an expression,
  196. a pointer to which is stored in *expp.
  197. */
  198. struct expr *ex = new_expr();
  199. *expp = ex;
  200. ex->ex_file = dot.tk_file;
  201. ex->ex_line = dot.tk_line;
  202. ex->ex_type = string_type;
  203. /* ex->ex_type = qualifier_type(ex->ex_type, TQ_CONST); */
  204. ex->ex_flags |= EX_READONLY;
  205. /* ex->ex_lvalue = 0; */
  206. ex->ex_class = String;
  207. ex->SG_VALUE = str;
  208. ex->SG_LEN = len;
  209. }
  210. void int2expr(struct expr *expr)
  211. {
  212. /* Dot contains an integer constant which is turned
  213. into an expression.
  214. */
  215. fill_int_expr(expr, dot.tk_ival, dot.tk_fund);
  216. }
  217. void float2expr(struct expr *expr)
  218. {
  219. /* Dot contains a floating point constant which is turned
  220. into an expression.
  221. */
  222. int fund;
  223. fund = dot.tk_fund;
  224. switch (fund) {
  225. case FLOAT:
  226. expr->ex_type = float_type;
  227. break;
  228. case DOUBLE:
  229. expr->ex_type = double_type;
  230. break;
  231. case LNGDBL:
  232. expr->ex_type = lngdbl_type;
  233. break;
  234. default:
  235. crash("(float2expr) bad fund %s\n", symbol2str(fund));
  236. }
  237. expr->ex_class = Float;
  238. flt_str2flt(dot.tk_fval, &(expr->FL_ARITH));
  239. free(dot.tk_fval);
  240. ASSERT(flt_status != FLT_NOFLT);
  241. if (flt_status == FLT_OVFL)
  242. expr_warning(expr,"internal floating point overflow");
  243. }
  244. struct expr *intexpr(arith ivalue, int fund)
  245. {
  246. /* The value ivalue is turned into an integer expression of
  247. the size indicated by fund.
  248. */
  249. struct expr *expr = new_expr();
  250. expr->ex_file = dot.tk_file;
  251. expr->ex_line = dot.tk_line;
  252. fill_int_expr(expr, ivalue, fund);
  253. return expr;
  254. }
  255. void fill_int_expr(struct expr *ex, arith ivalue, int fund)
  256. {
  257. /* Details derived from ivalue and fund are put into the
  258. constant integer expression ex.
  259. */
  260. switch (fund) {
  261. case INT:
  262. ex->ex_type = int_type;
  263. break;
  264. case UNSIGNED:
  265. ex->ex_type = uint_type;
  266. break;
  267. case LONG:
  268. ex->ex_type = long_type;
  269. break;
  270. case ULONG:
  271. ex->ex_type = ulong_type;
  272. break;
  273. default:
  274. crash("(fill_int_expr) bad fund %s\n", symbol2str(fund));
  275. /*NOTREACHED*/
  276. }
  277. ex->ex_class = Value;
  278. ex->VL_CLASS = Const;
  279. ex->VL_VALUE = ivalue;
  280. cut_size(ex);
  281. }
  282. struct expr *new_oper(struct type *tp, struct expr *e1, int oper, struct expr *e2)
  283. {
  284. /* A new expression is constructed which consists of the
  285. operator oper which has e1 and e2 as operands; for a
  286. monadic operator e1 == NILEXPR.
  287. During the construction of the right recursive initialisation
  288. tree it is possible for e2 to be NILEXPR.
  289. */
  290. struct expr *expr = new_expr();
  291. struct oper *op;
  292. if (e2) {
  293. struct expr *e = e2;
  294. while (e->ex_class == Oper && e->OP_LEFT)
  295. e = e->OP_LEFT;
  296. expr->ex_file = e->ex_file;
  297. expr->ex_line = e->ex_line;
  298. }
  299. else
  300. if (e1) {
  301. struct expr *e = e1;
  302. while (e->ex_class == Oper && e->OP_RIGHT)
  303. e = e->OP_RIGHT;
  304. expr->ex_file = e->ex_file;
  305. expr->ex_line = e->ex_line;
  306. }
  307. else {
  308. expr->ex_file = dot.tk_file;
  309. expr->ex_line = dot.tk_line;
  310. }
  311. expr->ex_type = tp;
  312. expr->ex_class = Oper;
  313. /* combine depths and flags of both expressions */
  314. if (e2) {
  315. int e1_depth = e1 ? e1->ex_depth : 0;
  316. int e1_flags = e1 ? e1->ex_flags : 0;
  317. expr->ex_depth =
  318. (e1_depth > e2->ex_depth ? e1_depth : e2->ex_depth) + 1;
  319. expr->ex_flags = (e1_flags | e2->ex_flags)
  320. & ~(EX_PARENS | EX_READONLY | EX_VOLATILE );
  321. }
  322. /*
  323. * A function call should be evaluated first when possible. Just say
  324. * that the expression tree is very deep.
  325. */
  326. if (oper == '(') {
  327. expr->ex_depth = 50;
  328. }
  329. op = &expr->ex_object.ex_oper;
  330. op->op_type = tp;
  331. op->op_oper = oper;
  332. op->op_left = e1;
  333. op->op_right = e2;
  334. #ifdef LINT
  335. lint_new_oper(expr);
  336. #endif /* LINT */
  337. return expr;
  338. }
  339. void chk_cst_expr(struct expr **expp)
  340. {
  341. /* The expression expr is checked for constancy.
  342. There are 6 places where constant expressions occur in C:
  343. 1. after #if
  344. 2. in a global initialization
  345. 3. as size in an array declaration
  346. 4. as value in an enum declaration
  347. 5. as width in a bit field
  348. 6. as case value in a switch
  349. The constant expression in a global initialization is
  350. handled separately (by IVAL()).
  351. There are various disparate restrictions on each of
  352. the others in the various C compilers. I have tried some
  353. hypotheses to unify them, but all have failed.
  354. Special problems (of which there is only one, sizeof in
  355. Preprocessor #if) have to be dealt with locally
  356. */
  357. struct expr *expr = *expp;
  358. #ifdef DEBUG
  359. print_expr("constant_expression", expr);
  360. #endif /* DEBUG */
  361. switch(expr->ex_type->tp_fund) {
  362. case CHAR:
  363. case SHORT:
  364. case INT:
  365. case ENUM:
  366. case LONG:
  367. if (is_ld_cst(expr)) {
  368. return;
  369. }
  370. expr_error(expr, "expression is not constant");
  371. break;
  372. default:
  373. expr_error(expr, "non-numerical constant expression");
  374. break;
  375. }
  376. erroneous2int(expp);
  377. }
  378. void init_expression(struct expr ***eppp, struct expr *expr)
  379. {
  380. /* The expression expr is added to the tree designated
  381. indirectly by **eppp.
  382. The natural form of a tree representing an
  383. initial_value_list is right-recursive, ie. with the
  384. left-most comma as main operator. The iterative grammar in
  385. expression.g, however, tends to produce a left-recursive
  386. tree, ie. one with the right-most comma as its main
  387. operator.
  388. To produce a right-recursive tree from the iterative
  389. grammar, we keep track of the address of the pointer where
  390. the next expression must be hooked in.
  391. */
  392. **eppp = new_oper(void_type, expr, INITCOMMA, NILEXPR);
  393. *eppp = &(**eppp)->OP_RIGHT;
  394. }
  395. int is_ld_cst(struct expr *expr)
  396. {
  397. /* An expression is a `load-time constant' if it is of the form
  398. <idf> +/- <integral> or <integral>.
  399. */
  400. #ifdef LINT
  401. if (expr->ex_class == String)
  402. return 1;
  403. #endif /* LINT */
  404. return expr->ex_lvalue == 0 && expr->ex_class == Value;
  405. }
  406. int is_cp_cst(struct expr *expr)
  407. {
  408. /* An expression is a `compile-time constant' if it is a
  409. load-time constant, and the idf is not there.
  410. */
  411. return is_ld_cst(expr) && expr->VL_CLASS == Const;
  412. }
  413. int is_fp_cst(struct expr *expr)
  414. {
  415. /* An expression is a `floating-point constant' if it consists
  416. of the float only.
  417. */
  418. return expr->ex_class == Float;
  419. }
  420. int is_zero_cst(struct expr *expr)
  421. {
  422. flt_arith var;
  423. switch(expr->ex_class) {
  424. case Value:
  425. return expr->VL_VALUE == 0;
  426. case Float:
  427. flt_arith2flt((arith) 0, &var, 0);
  428. return flt_cmp(&var, &(expr->FL_ARITH)) == 0;
  429. }
  430. /*NOTREACHED*/
  431. return 0;
  432. }
  433. void free_expression(struct expr *expr)
  434. {
  435. /* The expression expr is freed recursively.
  436. */
  437. if (expr) {
  438. if (expr->ex_class == Oper) {
  439. free_expression(expr->OP_LEFT);
  440. free_expression(expr->OP_RIGHT);
  441. }
  442. free_expr(expr);
  443. }
  444. }