c-expr.y 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. /* GCC-StarPU
  2. Copyright (C) 2011, 2012 Institut National de Recherche en Informatique et Automatique
  3. GCC-StarPU is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 3 of the License, or
  6. (at your option) any later version.
  7. GCC-StarPU is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with GCC-StarPU. If not, see <http://www.gnu.org/licenses/>. */
  13. /* Parser for simple C expressions in pragmas. */
  14. %define api.pure
  15. %parse-param { location_t loc }
  16. %parse-param { const char *pragma }
  17. %parse-param { tree *seq }
  18. %debug
  19. %{
  20. #include <starpu-gcc-config.h>
  21. #include <gcc-plugin.h>
  22. #include <plugin.h>
  23. #include <tree.h>
  24. #include <cpplib.h>
  25. #ifdef HAVE_C_FAMILY_C_COMMON_H
  26. # include <c-family/c-common.h>
  27. #elif HAVE_C_COMMON_H
  28. # include <c-common.h>
  29. #endif
  30. #ifdef HAVE_C_FAMILY_C_PRAGMA_H
  31. # include <c-family/c-pragma.h>
  32. #elif HAVE_C_PRAGMA_H
  33. # include <c-pragma.h>
  34. #endif
  35. #if !HAVE_DECL_BUILD_ARRAY_REF
  36. /* This declaration is missing in GCC 4.6.1. */
  37. extern tree build_array_ref (location_t loc, tree array, tree index);
  38. #endif
  39. #define YYSTYPE tree
  40. #define YYLTYPE location_t
  41. static void
  42. yyerror (location_t loc, const char *pragma, tree *seq,
  43. char const *message)
  44. {
  45. error_at (loc, "parse error in pragma %qs: %s", pragma, message);
  46. }
  47. /* Return SOMETHING if it's a VAR_DECL, an identifier bound to a VAR_DECL,
  48. or another object; raise an error otherwise. */
  49. static tree
  50. ensure_bound (location_t loc, tree something)
  51. {
  52. gcc_assert (something != NULL_TREE);
  53. if (DECL_P (something))
  54. return something;
  55. else if (TREE_CODE (something) == IDENTIFIER_NODE)
  56. {
  57. tree var = lookup_name (something);
  58. if (var == NULL_TREE)
  59. {
  60. error_at (loc, "unbound variable %qE", something);
  61. return error_mark_node;
  62. }
  63. else
  64. return var;
  65. }
  66. return something;
  67. }
  68. static tree
  69. build_component_ref (location_t loc, tree what, tree field)
  70. {
  71. sorry ("struct field access not implemented yet"); /* XXX */
  72. return error_mark_node;
  73. }
  74. %}
  75. %code {
  76. /* Mapping of libcpp token names to Bison-generated token names. This is
  77. not ideal but Bison cannot be told to use the `enum cpp_ttype'
  78. values. */
  79. #define STARPU_CPP_TOKENS \
  80. TK (CPP_NAME) \
  81. TK (CPP_NUMBER) \
  82. TK (CPP_AND) \
  83. TK (CPP_OPEN_SQUARE) \
  84. TK (CPP_CLOSE_SQUARE) \
  85. TK (CPP_OPEN_PAREN) \
  86. TK (CPP_CLOSE_PAREN) \
  87. TK (CPP_PLUS) \
  88. TK (CPP_MINUS) \
  89. TK (CPP_MULT) \
  90. TK (CPP_DIV) \
  91. TK (CPP_DOT) \
  92. TK (CPP_DEREF)
  93. #ifndef __cplusplus
  94. static const int cpplib_bison_token_map[] =
  95. {
  96. # define TK(x) [x] = Y ## x,
  97. STARPU_CPP_TOKENS
  98. # undef TK
  99. };
  100. #else /* __cplusplus */
  101. /* No designated initializers in C++. */
  102. static int cpplib_bison_token_map[CPP_PADDING];
  103. #endif /* __cplusplus */
  104. static int
  105. yylex (YYSTYPE *lvalp)
  106. {
  107. int ret;
  108. #ifdef __cplusplus
  109. if (cpplib_bison_token_map[CPP_NAME] != YCPP_NAME)
  110. {
  111. /* Initialize the table. */
  112. # define TK(x) cpplib_bison_token_map[x] = Y ## x;
  113. STARPU_CPP_TOKENS
  114. # undef TK
  115. }
  116. #endif
  117. ret = pragma_lex (lvalp);
  118. if (ret < sizeof cpplib_bison_token_map / sizeof cpplib_bison_token_map[0])
  119. ret = cpplib_bison_token_map[ret];
  120. else
  121. ret = -1;
  122. return ret;
  123. }
  124. }
  125. %token YCPP_NAME "identifier"
  126. %token YCPP_NUMBER "integer"
  127. %token YCPP_AND "&"
  128. %token YCPP_OPEN_SQUARE "["
  129. %token YCPP_CLOSE_SQUARE "]"
  130. %token YCPP_OPEN_PAREN "("
  131. %token YCPP_CLOSE_PAREN ")"
  132. %token YCPP_PLUS "+"
  133. %token YCPP_MINUS "-"
  134. %token YCPP_MULT "*"
  135. %token YCPP_DIV "/"
  136. %token YCPP_DOT "."
  137. %token YCPP_DEREF "->"
  138. %% /* Grammar rules. */
  139. /* Always return a TREE_LIST rather than a raw chain, because the elements
  140. of that list may be already chained for other purposes---e.g., PARM_DECLs
  141. of a function are chained together. */
  142. sequence: expression {
  143. gcc_assert (*seq == NULL_TREE);
  144. *seq = tree_cons (NULL_TREE, $1, NULL_TREE);
  145. $$ = *seq;
  146. }
  147. | expression sequence {
  148. gcc_assert ($2 == *seq);
  149. *seq = tree_cons (NULL_TREE, $1, $2);
  150. $$ = *seq;
  151. }
  152. ;
  153. expression: identifier | binary_expression | unary_expression;
  154. /* XXX: `ensure_bound' below leads to errors raised even for non-significant
  155. arguments---e.g., junk after pragma. */
  156. identifier: YCPP_NAME { $$ = ensure_bound (loc, $1); }
  157. ;
  158. binary_expression: multiplicative_expression
  159. | additive_expression
  160. ;
  161. multiplicative_expression: multiplicative_expression YCPP_MULT cast_expression {
  162. $$ = build_binary_op (UNKNOWN_LOCATION, MULT_EXPR, $1, $3, 0);
  163. }
  164. | multiplicative_expression YCPP_DIV cast_expression {
  165. $$ = build_binary_op (UNKNOWN_LOCATION, TRUNC_DIV_EXPR, $1, $3, 0);
  166. }
  167. | cast_expression
  168. ;
  169. additive_expression: multiplicative_expression
  170. | additive_expression YCPP_PLUS multiplicative_expression {
  171. $$ = build_binary_op (UNKNOWN_LOCATION, PLUS_EXPR, $1, $3, 0);
  172. }
  173. | additive_expression YCPP_MINUS multiplicative_expression {
  174. $$ = build_binary_op (UNKNOWN_LOCATION, MINUS_EXPR, $1, $3, 0);
  175. }
  176. ;
  177. cast_expression: unary_expression
  178. /* XXX: No support for '(' TYPE-NAME ')' UNARY-EXPRESSION. */
  179. ;
  180. unary_expression:
  181. primary_expression
  182. | postfix_expression
  183. | YCPP_AND cast_expression {
  184. $$ = build_addr (ensure_bound (loc, $2), current_function_decl);
  185. }
  186. ;
  187. postfix_expression:
  188. primary_expression
  189. | postfix_expression YCPP_OPEN_SQUARE expression YCPP_CLOSE_SQUARE {
  190. #if 1
  191. /* Build the array ref with proper error checking. */
  192. $$ = build_array_ref (loc, ensure_bound (loc, $1),
  193. ensure_bound (loc, $3));
  194. #else /* TIMTOWTDI */
  195. $$ = build_indirect_ref (loc,
  196. build_binary_op (loc, PLUS_EXPR, ensure_bound (loc, $1), ensure_bound (loc, $3), 0),
  197. RO_ARRAY_INDEXING);
  198. #endif
  199. }
  200. | postfix_expression YCPP_DOT identifier {
  201. $$ = build_component_ref (loc, ensure_bound (loc, $1), $2);
  202. }
  203. | postfix_expression YCPP_DEREF identifier {
  204. $$ = build_component_ref (loc,
  205. build_indirect_ref (loc, ensure_bound (loc, $1), RO_ARRAY_INDEXING),
  206. $2);
  207. }
  208. ;
  209. primary_expression: identifier
  210. | constant
  211. | YCPP_OPEN_PAREN expression YCPP_CLOSE_PAREN { $$ = $2; }
  212. ;
  213. constant: YCPP_NUMBER { $$ = $1; }
  214. ;
  215. %%