c-expr.y 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. /* GCC-StarPU
  2. Copyright (C) 2011 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. static const int cpplib_bison_token_map[] =
  80. {
  81. [CPP_NAME] = YCPP_NAME,
  82. [CPP_NUMBER] = YCPP_NUM,
  83. [CPP_AND] = YCPP_AND,
  84. [CPP_OPEN_SQUARE] = YCPP_OPEN_SQUARE,
  85. [CPP_CLOSE_SQUARE] = YCPP_CLOSE_SQUARE,
  86. [CPP_OPEN_PAREN] = YCPP_OPEN_PAREN,
  87. [CPP_CLOSE_PAREN] = YCPP_CLOSE_PAREN,
  88. [CPP_PLUS] = YCPP_PLUS,
  89. [CPP_MINUS] = YCPP_MINUS,
  90. [CPP_MULT] = YCPP_MULT,
  91. [CPP_DIV] = YCPP_DIV,
  92. [CPP_DOT] = YCPP_DOT,
  93. [CPP_DEREF] = YCPP_DEREF
  94. };
  95. static int
  96. yylex (YYSTYPE *lvalp)
  97. {
  98. int ret;
  99. ret = pragma_lex (lvalp);
  100. if (ret < sizeof cpplib_bison_token_map / sizeof cpplib_bison_token_map[0])
  101. ret = cpplib_bison_token_map[ret];
  102. else
  103. ret = -1;
  104. return ret;
  105. }
  106. }
  107. %token YCPP_NAME "identifier"
  108. %token YCPP_NUM "integer"
  109. %token YCPP_AND "&"
  110. %token YCPP_OPEN_SQUARE "["
  111. %token YCPP_CLOSE_SQUARE "]"
  112. %token YCPP_OPEN_PAREN "("
  113. %token YCPP_CLOSE_PAREN ")"
  114. %token YCPP_PLUS "+"
  115. %token YCPP_MINUS "-"
  116. %token YCPP_MULT "*"
  117. %token YCPP_DIV "/"
  118. %token YCPP_DOT "."
  119. %token YCPP_DEREF "->"
  120. %% /* Grammar rules. */
  121. /* Always return a TREE_LIST rather than a raw chain, because the elements
  122. of that list may be already chained for other purposes---e.g., PARM_DECLs
  123. of a function are chained together. */
  124. sequence: expression {
  125. gcc_assert (*seq == NULL_TREE);
  126. *seq = tree_cons (NULL_TREE, $1, NULL_TREE);
  127. $$ = *seq;
  128. }
  129. | expression sequence {
  130. gcc_assert ($2 == *seq);
  131. *seq = tree_cons (NULL_TREE, $1, $2);
  132. $$ = *seq;
  133. }
  134. ;
  135. expression: identifier | binary_expression | unary_expression;
  136. /* XXX: `ensure_bound' below leads to errors raised even for non-significant
  137. arguments---e.g., junk after pragma. */
  138. identifier: YCPP_NAME { $$ = ensure_bound (loc, $1); }
  139. ;
  140. binary_expression: multiplicative_expression
  141. | additive_expression
  142. ;
  143. multiplicative_expression: multiplicative_expression YCPP_MULT cast_expression {
  144. $$ = build_binary_op (UNKNOWN_LOCATION, MULT_EXPR, $1, $3, 0);
  145. }
  146. | multiplicative_expression YCPP_DIV cast_expression {
  147. $$ = build_binary_op (UNKNOWN_LOCATION, TRUNC_DIV_EXPR, $1, $3, 0);
  148. }
  149. | cast_expression
  150. ;
  151. additive_expression: multiplicative_expression
  152. | additive_expression YCPP_PLUS multiplicative_expression {
  153. $$ = build_binary_op (UNKNOWN_LOCATION, PLUS_EXPR, $1, $3, 0);
  154. }
  155. | additive_expression YCPP_MINUS multiplicative_expression {
  156. $$ = build_binary_op (UNKNOWN_LOCATION, MINUS_EXPR, $1, $3, 0);
  157. }
  158. ;
  159. cast_expression: unary_expression
  160. /* XXX: No support for '(' TYPE-NAME ')' UNARY-EXPRESSION. */
  161. ;
  162. unary_expression:
  163. primary_expression
  164. | postfix_expression
  165. | YCPP_AND cast_expression {
  166. $$ = build_addr (ensure_bound (loc, $2), current_function_decl);
  167. }
  168. ;
  169. postfix_expression:
  170. primary_expression
  171. | postfix_expression YCPP_OPEN_SQUARE expression YCPP_CLOSE_SQUARE {
  172. #if 1
  173. /* Build the array ref with proper error checking. */
  174. $$ = build_array_ref (loc, ensure_bound (loc, $1),
  175. ensure_bound (loc, $3));
  176. #else /* TIMTOWTDI */
  177. $$ = build_indirect_ref (loc,
  178. build_binary_op (loc, PLUS_EXPR, ensure_bound (loc, $1), ensure_bound (loc, $3), 0),
  179. RO_ARRAY_INDEXING);
  180. #endif
  181. }
  182. | postfix_expression YCPP_DOT identifier {
  183. $$ = build_component_ref (loc, ensure_bound (loc, $1), $2);
  184. }
  185. | postfix_expression YCPP_DEREF identifier {
  186. $$ = build_component_ref (loc,
  187. build_indirect_ref (loc, ensure_bound (loc, $1), RO_ARRAY_INDEXING),
  188. $2);
  189. }
  190. ;
  191. primary_expression: identifier
  192. | constant
  193. | YCPP_OPEN_PAREN expression YCPP_CLOSE_PAREN { $$ = $2; }
  194. ;
  195. constant: YCPP_NUM { $$ = $1; }
  196. ;
  197. %%