f-exp.h 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. /* Definitions for Fortran expressions
  2. Copyright (C) 2020-2022 Free Software Foundation, Inc.
  3. This file is part of GDB.
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 3 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  14. #ifndef FORTRAN_EXP_H
  15. #define FORTRAN_EXP_H
  16. #include "expop.h"
  17. extern struct value *eval_op_f_abs (struct type *expect_type,
  18. struct expression *exp,
  19. enum noside noside,
  20. enum exp_opcode opcode,
  21. struct value *arg1);
  22. extern struct value *eval_op_f_mod (struct type *expect_type,
  23. struct expression *exp,
  24. enum noside noside,
  25. enum exp_opcode opcode,
  26. struct value *arg1, struct value *arg2);
  27. extern struct value *eval_op_f_ceil (struct type *expect_type,
  28. struct expression *exp,
  29. enum noside noside,
  30. enum exp_opcode opcode,
  31. struct value *arg1);
  32. extern struct value *eval_op_f_floor (struct type *expect_type,
  33. struct expression *exp,
  34. enum noside noside,
  35. enum exp_opcode opcode,
  36. struct value *arg1);
  37. extern struct value *eval_op_f_modulo (struct type *expect_type,
  38. struct expression *exp,
  39. enum noside noside,
  40. enum exp_opcode opcode,
  41. struct value *arg1, struct value *arg2);
  42. extern struct value *eval_op_f_cmplx (struct type *expect_type,
  43. struct expression *exp,
  44. enum noside noside,
  45. enum exp_opcode opcode,
  46. struct value *arg1, struct value *arg2);
  47. extern struct value *eval_op_f_kind (struct type *expect_type,
  48. struct expression *exp,
  49. enum noside noside,
  50. enum exp_opcode opcode,
  51. struct value *arg1);
  52. extern struct value *eval_op_f_associated (struct type *expect_type,
  53. struct expression *exp,
  54. enum noside noside,
  55. enum exp_opcode opcode,
  56. struct value *arg1);
  57. extern struct value *eval_op_f_associated (struct type *expect_type,
  58. struct expression *exp,
  59. enum noside noside,
  60. enum exp_opcode opcode,
  61. struct value *arg1,
  62. struct value *arg2);
  63. extern struct value * eval_op_f_allocated (struct type *expect_type,
  64. struct expression *exp,
  65. enum noside noside,
  66. enum exp_opcode op,
  67. struct value *arg1);
  68. extern struct value * eval_op_f_loc (struct type *expect_type,
  69. struct expression *exp,
  70. enum noside noside,
  71. enum exp_opcode op,
  72. struct value *arg1);
  73. /* Implement the evaluation of UNOP_FORTRAN_RANK. EXPECTED_TYPE, EXP, and
  74. NOSIDE are as for expression::evaluate (see expression.h). OP will
  75. always be UNOP_FORTRAN_RANK, and ARG1 is the argument being passed to
  76. the expression. */
  77. extern struct value *eval_op_f_rank (struct type *expect_type,
  78. struct expression *exp,
  79. enum noside noside,
  80. enum exp_opcode op,
  81. struct value *arg1);
  82. /* Implement expression evaluation for Fortran's SIZE keyword. For
  83. EXPECT_TYPE, EXP, and NOSIDE see expression::evaluate (in
  84. expression.h). OP will always for FORTRAN_ARRAY_SIZE. ARG1 is the
  85. value passed to SIZE if it is only passed a single argument. For the
  86. two argument form see the overload of this function below. */
  87. extern struct value *eval_op_f_array_size (struct type *expect_type,
  88. struct expression *exp,
  89. enum noside noside,
  90. enum exp_opcode opcode,
  91. struct value *arg1);
  92. /* An overload of EVAL_OP_F_ARRAY_SIZE above, this version takes two
  93. arguments, representing the two values passed to Fortran's SIZE
  94. keyword. */
  95. extern struct value *eval_op_f_array_size (struct type *expect_type,
  96. struct expression *exp,
  97. enum noside noside,
  98. enum exp_opcode opcode,
  99. struct value *arg1,
  100. struct value *arg2);
  101. /* Implement the evaluation of Fortran's SHAPE keyword. EXPECTED_TYPE,
  102. EXP, and NOSIDE are as for expression::evaluate (see expression.h). OP
  103. will always be UNOP_FORTRAN_SHAPE, and ARG1 is the argument being passed
  104. to the expression. */
  105. extern struct value *eval_op_f_array_shape (struct type *expect_type,
  106. struct expression *exp,
  107. enum noside noside,
  108. enum exp_opcode op,
  109. struct value *arg1);
  110. namespace expr
  111. {
  112. using fortran_abs_operation = unop_operation<UNOP_ABS, eval_op_f_abs>;
  113. using fortran_ceil_operation = unop_operation<UNOP_FORTRAN_CEILING,
  114. eval_op_f_ceil>;
  115. using fortran_floor_operation = unop_operation<UNOP_FORTRAN_FLOOR,
  116. eval_op_f_floor>;
  117. using fortran_kind_operation = unop_operation<UNOP_FORTRAN_KIND,
  118. eval_op_f_kind>;
  119. using fortran_allocated_operation = unop_operation<UNOP_FORTRAN_ALLOCATED,
  120. eval_op_f_allocated>;
  121. using fortran_loc_operation = unop_operation<UNOP_FORTRAN_LOC,
  122. eval_op_f_loc>;
  123. using fortran_mod_operation = binop_operation<BINOP_MOD, eval_op_f_mod>;
  124. using fortran_modulo_operation = binop_operation<BINOP_FORTRAN_MODULO,
  125. eval_op_f_modulo>;
  126. using fortran_associated_1arg = unop_operation<FORTRAN_ASSOCIATED,
  127. eval_op_f_associated>;
  128. using fortran_associated_2arg = binop_operation<FORTRAN_ASSOCIATED,
  129. eval_op_f_associated>;
  130. using fortran_rank_operation = unop_operation<UNOP_FORTRAN_RANK,
  131. eval_op_f_rank>;
  132. using fortran_array_size_1arg = unop_operation<FORTRAN_ARRAY_SIZE,
  133. eval_op_f_array_size>;
  134. using fortran_array_size_2arg = binop_operation<FORTRAN_ARRAY_SIZE,
  135. eval_op_f_array_size>;
  136. using fortran_array_shape_operation = unop_operation<UNOP_FORTRAN_SHAPE,
  137. eval_op_f_array_shape>;
  138. /* The Fortran "complex" operation. */
  139. class fortran_cmplx_operation
  140. : public tuple_holding_operation<operation_up, operation_up>
  141. {
  142. public:
  143. using tuple_holding_operation::tuple_holding_operation;
  144. value *evaluate (struct type *expect_type,
  145. struct expression *exp,
  146. enum noside noside) override
  147. {
  148. value *arg1 = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
  149. value *arg2 = std::get<1> (m_storage)->evaluate (value_type (arg1),
  150. exp, noside);
  151. return eval_op_f_cmplx (expect_type, exp, noside, BINOP_FORTRAN_CMPLX,
  152. arg1, arg2);
  153. }
  154. enum exp_opcode opcode () const override
  155. { return BINOP_FORTRAN_CMPLX; }
  156. };
  157. /* OP_RANGE for Fortran. */
  158. class fortran_range_operation
  159. : public tuple_holding_operation<enum range_flag, operation_up, operation_up,
  160. operation_up>
  161. {
  162. public:
  163. using tuple_holding_operation::tuple_holding_operation;
  164. value *evaluate (struct type *expect_type,
  165. struct expression *exp,
  166. enum noside noside) override
  167. {
  168. error (_("ranges not allowed in this context"));
  169. }
  170. range_flag get_flags () const
  171. {
  172. return std::get<0> (m_storage);
  173. }
  174. value *evaluate0 (struct expression *exp, enum noside noside) const
  175. {
  176. return std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
  177. }
  178. value *evaluate1 (struct expression *exp, enum noside noside) const
  179. {
  180. return std::get<2> (m_storage)->evaluate (nullptr, exp, noside);
  181. }
  182. value *evaluate2 (struct expression *exp, enum noside noside) const
  183. {
  184. return std::get<3> (m_storage)->evaluate (nullptr, exp, noside);
  185. }
  186. enum exp_opcode opcode () const override
  187. { return OP_RANGE; }
  188. };
  189. /* In F77, functions, substring ops and array subscript operations
  190. cannot be disambiguated at parse time. This operation handles
  191. both, deciding which do to at evaluation time. */
  192. class fortran_undetermined
  193. : public tuple_holding_operation<operation_up, std::vector<operation_up>>
  194. {
  195. public:
  196. using tuple_holding_operation::tuple_holding_operation;
  197. value *evaluate (struct type *expect_type,
  198. struct expression *exp,
  199. enum noside noside) override;
  200. enum exp_opcode opcode () const override
  201. { return OP_F77_UNDETERMINED_ARGLIST; }
  202. private:
  203. value *value_subarray (value *array, struct expression *exp,
  204. enum noside noside);
  205. };
  206. /* Single-argument form of Fortran ubound/lbound intrinsics. */
  207. class fortran_bound_1arg
  208. : public tuple_holding_operation<exp_opcode, operation_up>
  209. {
  210. public:
  211. using tuple_holding_operation::tuple_holding_operation;
  212. value *evaluate (struct type *expect_type,
  213. struct expression *exp,
  214. enum noside noside) override;
  215. enum exp_opcode opcode () const override
  216. { return std::get<0> (m_storage); }
  217. };
  218. /* Two-argument form of Fortran ubound/lbound intrinsics. */
  219. class fortran_bound_2arg
  220. : public tuple_holding_operation<exp_opcode, operation_up, operation_up>
  221. {
  222. public:
  223. using tuple_holding_operation::tuple_holding_operation;
  224. value *evaluate (struct type *expect_type,
  225. struct expression *exp,
  226. enum noside noside) override;
  227. enum exp_opcode opcode () const override
  228. { return std::get<0> (m_storage); }
  229. };
  230. /* Implement STRUCTOP_STRUCT for Fortran. */
  231. class fortran_structop_operation
  232. : public structop_base_operation
  233. {
  234. public:
  235. using structop_base_operation::structop_base_operation;
  236. value *evaluate (struct type *expect_type,
  237. struct expression *exp,
  238. enum noside noside) override;
  239. enum exp_opcode opcode () const override
  240. { return STRUCTOP_STRUCT; }
  241. };
  242. } /* namespace expr */
  243. #endif /* FORTRAN_EXP_H */