ch7mon.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  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. /* $Header$ */
  6. /* SEMANTIC ANALYSIS (CHAPTER 3.3) -- MONADIC OPERATORS */
  7. #include "botch_free.h"
  8. #include <alloc.h>
  9. #include "nobitfield.h"
  10. #include "Lpars.h"
  11. #include <flt_arith.h>
  12. #include "arith.h"
  13. #include "type.h"
  14. #include "label.h"
  15. #include "expr.h"
  16. #include "idf.h"
  17. #include "def.h"
  18. extern char options[];
  19. extern arith full_mask[/*MAXSIZE*/]; /* cstoper.c */
  20. char *symbol2str();
  21. ch7mon(oper, expp)
  22. register struct expr **expp;
  23. {
  24. /* The monadic prefix operator oper is applied to *expp.
  25. */
  26. register struct expr *expr;
  27. switch (oper) {
  28. case '*': /* 3.3.3.2 */
  29. /* no FIELD type allowed */
  30. if ((*expp)->ex_type->tp_fund == ARRAY)
  31. array2pointer(*expp);
  32. if ((*expp)->ex_type->tp_fund != POINTER) {
  33. if ((*expp)->ex_type->tp_fund != FUNCTION) {
  34. expr_error(*expp,
  35. "* applied to non-pointer (%s)",
  36. symbol2str((*expp)->ex_type->tp_fund));
  37. } else {
  38. warning("superfluous use of * on function");
  39. /* ignore indirection (yegh) */
  40. }
  41. } else {
  42. expr = *expp;
  43. if (expr->ex_lvalue == 0 && expr->ex_class != String)
  44. /* dereference in administration only */
  45. expr->ex_type = expr->ex_type->tp_up;
  46. else /* runtime code */
  47. *expp = new_oper(expr->ex_type->tp_up, NILEXPR,
  48. '*', expr);
  49. (*expp)->ex_lvalue = (
  50. (*expp)->ex_type->tp_fund != ARRAY &&
  51. (*expp)->ex_type->tp_fund != FUNCTION
  52. );
  53. if ((*expp)->ex_type->tp_typequal & TQ_CONST)
  54. (*expp)->ex_flags |= EX_READONLY;
  55. if ((*expp)->ex_type->tp_typequal & TQ_VOLATILE)
  56. (*expp)->ex_flags |= EX_VOLATILE;
  57. (*expp)->ex_flags &= ~EX_ILVALUE;
  58. }
  59. break;
  60. case '&':
  61. if ((*expp)->ex_type->tp_fund == ARRAY) {
  62. expr_warning(*expp, "& before array ignored");
  63. array2pointer(*expp);
  64. }
  65. else
  66. if ((*expp)->ex_type->tp_fund == FUNCTION) {
  67. expr_warning(*expp, "& before function ignored");
  68. function2pointer(*expp);
  69. }
  70. else
  71. #ifndef NOBITFIELD
  72. if ((*expp)->ex_type->tp_fund == FIELD)
  73. expr_error(*expp, "& applied to field variable");
  74. else
  75. #endif NOBITFIELD
  76. if (!(*expp)->ex_lvalue)
  77. expr_error(*expp, "& applied to non-lvalue");
  78. else if ((*expp)->ex_flags & EX_ILVALUE)
  79. expr_error(*expp, "& applied to illegal lvalue");
  80. else {
  81. /* assume that enums are already filtered out */
  82. if (ISNAME(*expp)) {
  83. register struct def *def =
  84. (*expp)->VL_IDF->id_def;
  85. /* &<var> indicates that <var>
  86. cannot be used as register
  87. anymore
  88. */
  89. if (def->df_sc == REGISTER) {
  90. expr_error(*expp,
  91. "& on register variable not allowed");
  92. break; /* break case '&' */
  93. }
  94. }
  95. (*expp)->ex_type = pointer_to((*expp)->ex_type,
  96. (*expp)->ex_type->tp_typequal);
  97. (*expp)->ex_lvalue = 0;
  98. (*expp)->ex_flags &= ~EX_READONLY;
  99. }
  100. break;
  101. case '~':
  102. {
  103. int fund = (*expp)->ex_type->tp_fund;
  104. if (fund == FLOAT || fund == DOUBLE || fund == LNGDBL) {
  105. expr_error( *expp,
  106. "~ not allowed on %s operands",
  107. symbol2str(fund));
  108. erroneous2int(expp);
  109. break;
  110. }
  111. /* FALLTHROUGH */
  112. }
  113. case '-':
  114. any2arith(expp, oper);
  115. if (is_cp_cst(*expp)) {
  116. arith o1 = (*expp)->VL_VALUE;
  117. (*expp)->VL_VALUE = (oper == '-') ? -o1 :
  118. ((*expp)->ex_type->tp_unsigned ?
  119. (~o1) & full_mask[(*expp)->ex_type->tp_size] :
  120. ~o1
  121. );
  122. }
  123. else
  124. if (is_fp_cst(*expp))
  125. switch_sign_fp(*expp);
  126. else
  127. *expp = new_oper((*expp)->ex_type,
  128. NILEXPR, oper, *expp);
  129. break;
  130. case '!':
  131. if ((*expp)->ex_type->tp_fund == FUNCTION)
  132. function2pointer(*expp);
  133. if ((*expp)->ex_type->tp_fund != POINTER)
  134. any2arith(expp, oper);
  135. opnd2test(expp, '!');
  136. if (is_cp_cst(*expp)) {
  137. (*expp)->VL_VALUE = !((*expp)->VL_VALUE);
  138. (*expp)->ex_type = int_type; /* a cast ???(EB) */
  139. }
  140. else
  141. *expp = new_oper(int_type, NILEXPR, oper, *expp);
  142. (*expp)->ex_flags |= EX_LOGICAL;
  143. break;
  144. case PLUSPLUS:
  145. case MINMIN:
  146. ch7incr(expp, oper);
  147. break;
  148. case SIZEOF:
  149. if (ISNAME(*expp) && (*expp)->VL_IDF->id_def->df_formal_array)
  150. expr_warning(*expp, "sizeof formal array %s is sizeof pointer!",
  151. (*expp)->VL_IDF->id_text);
  152. expr = intexpr((*expp)->ex_class == String ?
  153. (arith)((*expp)->SG_LEN) :
  154. size_of_type((*expp)->ex_type, "object"),
  155. INT);
  156. expr->ex_flags |= EX_SIZEOF;
  157. free_expression(*expp);
  158. *expp = expr;
  159. break;
  160. }
  161. }