Branch data Line data Source code
1 : : /* jit.c -- Dummy "frontend" for use during JIT-compilation.
2 : : Copyright (C) 2013-2024 Free Software Foundation, Inc.
3 : :
4 : : This file is part of GCC.
5 : :
6 : : GCC is free software; you can redistribute it and/or modify it under
7 : : the terms of the GNU General Public License as published by the Free
8 : : Software Foundation; either version 3, or (at your option) any later
9 : : version.
10 : :
11 : : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 : : WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 : : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 : : for more details.
15 : :
16 : : You should have received a copy of the GNU General Public License
17 : : along with GCC; see the file COPYING3. If not see
18 : : <http://www.gnu.org/licenses/>. */
19 : :
20 : : #include "config.h"
21 : : #include "system.h"
22 : : #include "coretypes.h"
23 : : #include "jit-playback.h"
24 : : #include "stor-layout.h"
25 : : #include "debug.h"
26 : : #include "langhooks.h"
27 : : #include "langhooks-def.h"
28 : : #include "diagnostic.h"
29 : : #include "options.h"
30 : : #include "stringpool.h"
31 : : #include "attribs.h"
32 : : #include "cgraph.h"
33 : : #include "target.h"
34 : :
35 : : #include <mpfr.h>
36 : :
37 : : /* Attribute handling. */
38 : :
39 : : static tree handle_alias_attribute (tree *, tree, tree, int, bool *);
40 : : static tree handle_always_inline_attribute (tree *, tree, tree, int,
41 : : bool *);
42 : : static tree handle_cold_attribute (tree *, tree, tree, int, bool *);
43 : : static tree handle_const_attribute (tree *, tree, tree, int, bool *);
44 : : static tree handle_fnspec_attribute (tree *, tree, tree, int, bool *);
45 : : static tree handle_format_arg_attribute (tree *, tree, tree, int, bool *);
46 : : static tree handle_format_attribute (tree *, tree, tree, int, bool *);
47 : : static tree handle_leaf_attribute (tree *, tree, tree, int, bool *);
48 : : static tree handle_malloc_attribute (tree *, tree, tree, int, bool *);
49 : : static tree handle_noinline_attribute (tree *, tree, tree, int, bool *);
50 : : static tree handle_nonnull_attribute (tree *, tree, tree, int, bool *);
51 : : static tree handle_noreturn_attribute (tree *, tree, tree, int, bool *);
52 : : static tree handle_nothrow_attribute (tree *, tree, tree, int, bool *);
53 : : static tree handle_novops_attribute (tree *, tree, tree, int, bool *);
54 : : static tree handle_patchable_function_entry_attribute (tree *, tree, tree,
55 : : int, bool *);
56 : : static tree handle_pure_attribute (tree *, tree, tree, int, bool *);
57 : : static tree handle_returns_twice_attribute (tree *, tree, tree, int, bool *);
58 : : static tree handle_sentinel_attribute (tree *, tree, tree, int, bool *);
59 : : static tree handle_target_attribute (tree *, tree, tree, int, bool *);
60 : : static tree handle_transaction_pure_attribute (tree *, tree, tree, int, bool *);
61 : : static tree handle_type_generic_attribute (tree *, tree, tree, int, bool *);
62 : : static tree handle_used_attribute (tree *, tree, tree, int, bool *);
63 : : static tree handle_visibility_attribute (tree *, tree, tree, int,
64 : : bool *);
65 : : static tree handle_weak_attribute (tree *, tree, tree, int, bool *) ;
66 : :
67 : : static tree ignore_attribute (tree *, tree, tree, int, bool *);
68 : :
69 : : /* Helper to define attribute exclusions. */
70 : : #define ATTR_EXCL(name, function, type, variable) \
71 : : { name, function, type, variable }
72 : :
73 : : /* Define attributes that are mutually exclusive with one another. */
74 : : static const struct attribute_spec::exclusions attr_noreturn_exclusions[] =
75 : : {
76 : : ATTR_EXCL ("alloc_align", true, true, true),
77 : : ATTR_EXCL ("alloc_size", true, true, true),
78 : : ATTR_EXCL ("const", true, true, true),
79 : : ATTR_EXCL ("malloc", true, true, true),
80 : : ATTR_EXCL ("pure", true, true, true),
81 : : ATTR_EXCL ("returns_twice", true, true, true),
82 : : ATTR_EXCL ("warn_unused_result", true, true, true),
83 : : ATTR_EXCL (NULL, false, false, false),
84 : : };
85 : :
86 : : static const struct attribute_spec::exclusions attr_returns_twice_exclusions[] =
87 : : {
88 : : ATTR_EXCL ("noreturn", true, true, true),
89 : : ATTR_EXCL (NULL, false, false, false),
90 : : };
91 : :
92 : : /* Exclusions that apply to attribute alloc_align, alloc_size, and malloc. */
93 : : static const struct attribute_spec::exclusions attr_alloc_exclusions[] =
94 : : {
95 : : ATTR_EXCL ("const", true, true, true),
96 : : ATTR_EXCL ("noreturn", true, true, true),
97 : : ATTR_EXCL ("pure", true, true, true),
98 : : ATTR_EXCL (NULL, false, false, false),
99 : : };
100 : :
101 : : static const struct attribute_spec::exclusions attr_const_pure_exclusions[] =
102 : : {
103 : : ATTR_EXCL ("const", true, true, true),
104 : : ATTR_EXCL ("alloc_align", true, true, true),
105 : : ATTR_EXCL ("alloc_size", true, true, true),
106 : : ATTR_EXCL ("malloc", true, true, true),
107 : : ATTR_EXCL ("noreturn", true, true, true),
108 : : ATTR_EXCL ("pure", true, true, true),
109 : : ATTR_EXCL (NULL, false, false, false)
110 : : };
111 : :
112 : : static const struct attribute_spec::exclusions attr_always_inline_exclusions[] =
113 : : {
114 : : ATTR_EXCL ("noinline", true, true, true),
115 : : ATTR_EXCL ("target_clones", true, true, true),
116 : : ATTR_EXCL (NULL, false, false, false),
117 : : };
118 : :
119 : : extern const struct attribute_spec::exclusions attr_cold_hot_exclusions[] =
120 : : {
121 : : ATTR_EXCL ("cold", true, true, true),
122 : : ATTR_EXCL ("hot", true, true, true),
123 : : ATTR_EXCL (NULL, false, false, false)
124 : : };
125 : :
126 : : static const struct attribute_spec::exclusions attr_noinline_exclusions[] =
127 : : {
128 : : ATTR_EXCL ("always_inline", true, true, true),
129 : : ATTR_EXCL ("gnu_inline", true, true, true),
130 : : ATTR_EXCL (NULL, false, false, false),
131 : : };
132 : :
133 : : static const struct attribute_spec::exclusions attr_target_exclusions[] =
134 : : {
135 : : ATTR_EXCL ("target_clones", TARGET_HAS_FMV_TARGET_ATTRIBUTE,
136 : : TARGET_HAS_FMV_TARGET_ATTRIBUTE, TARGET_HAS_FMV_TARGET_ATTRIBUTE),
137 : : ATTR_EXCL (NULL, false, false, false),
138 : : };
139 : :
140 : : /* Table of machine-independent attributes supported in libgccjit. */
141 : : static const attribute_spec jit_gnu_attributes[] =
142 : : {
143 : : /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
144 : : affects_type_identity, handler, exclude } */
145 : : { "alias", 1, 1, true, false, false, false,
146 : : handle_alias_attribute, NULL },
147 : : { "always_inline", 0, 0, true, false, false, false,
148 : : handle_always_inline_attribute,
149 : : attr_always_inline_exclusions },
150 : : { "cold", 0, 0, true, false, false, false,
151 : : handle_cold_attribute,
152 : : attr_cold_hot_exclusions },
153 : : /* The same comments as for noreturn attributes apply to const ones. */
154 : : { "const", 0, 0, true, false, false, false,
155 : : handle_const_attribute,
156 : : attr_const_pure_exclusions },
157 : : { "fn spec", 1, 1, false, true, true, false,
158 : : handle_fnspec_attribute, NULL },
159 : :
160 : : { "leaf", 0, 0, true, false, false, false,
161 : : handle_leaf_attribute, NULL },
162 : : { "malloc", 0, 0, true, false, false, false,
163 : : handle_malloc_attribute, attr_alloc_exclusions },
164 : : { "noreturn", 0, 0, true, false, false, false,
165 : : handle_noreturn_attribute,
166 : : attr_noreturn_exclusions },
167 : : { "no vops", 0, 0, true, false, false, false,
168 : : handle_novops_attribute, NULL },
169 : : { "noinline", 0, 0, true, false, false, false,
170 : : handle_noinline_attribute,
171 : : attr_noinline_exclusions },
172 : : { "nonnull", 0, -1, false, true, true, false,
173 : : handle_nonnull_attribute, NULL },
174 : : { "nothrow", 0, 0, true, false, false, false,
175 : : handle_nothrow_attribute, NULL },
176 : : { "patchable_function_entry", 1, 2, true, false, false, false,
177 : : handle_patchable_function_entry_attribute,
178 : : NULL },
179 : : { "pure", 0, 0, true, false, false, false,
180 : : handle_pure_attribute,
181 : : attr_const_pure_exclusions },
182 : : { "returns_twice", 0, 0, true, false, false, false,
183 : : handle_returns_twice_attribute,
184 : : attr_returns_twice_exclusions },
185 : : { "sentinel", 0, 1, false, true, true, false,
186 : : handle_sentinel_attribute, NULL },
187 : : { "target", 1, -1, true, false, false, false,
188 : : handle_target_attribute, attr_target_exclusions },
189 : : { "type generic", 0, 0, false, true, true, false,
190 : : handle_type_generic_attribute, NULL },
191 : : { "transaction_pure", 0, 0, false, true, true, false,
192 : : handle_transaction_pure_attribute, NULL },
193 : : { "used", 0, 0, true, false, false, false,
194 : : handle_used_attribute, NULL },
195 : : { "visibility", 1, 1, false, false, false, false,
196 : : handle_visibility_attribute, NULL },
197 : : { "weak", 0, 0, true, false, false, false,
198 : : handle_weak_attribute, NULL },
199 : : /* For internal use only. The leading '*' both prevents its usage in
200 : : source code and signals that it may be overridden by machine tables. */
201 : : { "*tm regparm", 0, 0, false, true, true, false,
202 : : ignore_attribute, NULL },
203 : : };
204 : :
205 : : static const scoped_attribute_specs jit_gnu_attribute_table =
206 : : {
207 : : "gnu", { jit_gnu_attributes }
208 : : };
209 : :
210 : : /* Give the specifications for the format attributes, used by C and all
211 : : descendants. */
212 : :
213 : : static const attribute_spec jit_format_attributes[] =
214 : : {
215 : : /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
216 : : affects_type_identity, handler, exclude } */
217 : : { "format", 3, 3, false, true, true, false,
218 : : handle_format_attribute, NULL },
219 : : { "format_arg", 1, 1, false, true, true, false,
220 : : handle_format_arg_attribute, NULL }
221 : : };
222 : :
223 : : static const scoped_attribute_specs jit_format_attribute_table =
224 : : {
225 : : "gnu", { jit_format_attributes }
226 : : };
227 : :
228 : : static const scoped_attribute_specs *const jit_attribute_table[] =
229 : : {
230 : : &jit_gnu_attribute_table,
231 : : &jit_format_attribute_table
232 : : };
233 : :
234 : : /* Attribute handlers. */
235 : :
236 : : /* Handle a "noreturn" attribute; arguments as in
237 : : struct attribute_spec.handler. */
238 : :
239 : : static tree
240 : 1148 : handle_noreturn_attribute (tree *node, tree ARG_UNUSED (name),
241 : : tree ARG_UNUSED (args), int ARG_UNUSED (flags),
242 : : bool * ARG_UNUSED (no_add_attrs))
243 : : {
244 : 1148 : tree type = TREE_TYPE (*node);
245 : :
246 : 1148 : if (TREE_CODE (*node) == FUNCTION_DECL)
247 : 1148 : TREE_THIS_VOLATILE (*node) = 1;
248 : 0 : else if (TREE_CODE (type) == POINTER_TYPE
249 : 0 : && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
250 : 0 : TREE_TYPE (*node)
251 : 0 : = build_pointer_type
252 : 0 : (build_type_variant (TREE_TYPE (type),
253 : : TYPE_READONLY (TREE_TYPE (type)), 1));
254 : : else
255 : 0 : gcc_unreachable ();
256 : :
257 : 1148 : return NULL_TREE;
258 : : }
259 : :
260 : : /* Handle a "leaf" attribute; arguments as in
261 : : struct attribute_spec.handler. */
262 : :
263 : : static tree
264 : 4797 : handle_leaf_attribute (tree *node, tree name,
265 : : tree ARG_UNUSED (args),
266 : : int ARG_UNUSED (flags), bool *no_add_attrs)
267 : : {
268 : 4797 : if (TREE_CODE (*node) != FUNCTION_DECL)
269 : : {
270 : 0 : warning (OPT_Wattributes, "%qE attribute ignored", name);
271 : 0 : *no_add_attrs = true;
272 : : }
273 : 4797 : if (!TREE_PUBLIC (*node))
274 : : {
275 : 0 : warning (OPT_Wattributes, "%qE attribute has no effect on unit local functions", name);
276 : 0 : *no_add_attrs = true;
277 : : }
278 : :
279 : 4797 : return NULL_TREE;
280 : : }
281 : :
282 : : /* Handle a "const" attribute; arguments as in
283 : : struct attribute_spec.handler. */
284 : :
285 : : static tree
286 : 3484 : handle_const_attribute (tree *node, tree name, tree ARG_UNUSED (args),
287 : : int ARG_UNUSED (flags), bool *no_add_attrs)
288 : : {
289 : 3484 : tree type = TREE_TYPE (*node);
290 : :
291 : : /* See FIXME comment on noreturn in c_common_attribute_table. */
292 : 3484 : if (TREE_CODE (*node) == FUNCTION_DECL)
293 : 3484 : TREE_READONLY (*node) = 1;
294 : 0 : else if (TREE_CODE (type) == POINTER_TYPE
295 : 0 : && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
296 : 0 : TREE_TYPE (*node)
297 : 0 : = (build_qualified_type
298 : 0 : (build_pointer_type
299 : 0 : (build_type_variant (TREE_TYPE (type), 1,
300 : : TREE_THIS_VOLATILE (TREE_TYPE (type)))),
301 : 0 : TYPE_QUALS (type)));
302 : : else
303 : : {
304 : 0 : warning (OPT_Wattributes, "%qE attribute ignored", name);
305 : 0 : *no_add_attrs = true;
306 : : }
307 : :
308 : 3484 : return NULL_TREE;
309 : : }
310 : :
311 : :
312 : : /* Handle a "malloc" attribute; arguments as in
313 : : struct attribute_spec.handler. */
314 : :
315 : : static tree
316 : 0 : handle_malloc_attribute (tree *node, tree ARG_UNUSED (name),
317 : : tree ARG_UNUSED (args), int ARG_UNUSED (flags),
318 : : bool * ARG_UNUSED (no_add_attrs))
319 : : {
320 : 0 : if (TREE_CODE (*node) == FUNCTION_DECL
321 : 0 : && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (*node))))
322 : 0 : DECL_IS_MALLOC (*node) = 1;
323 : : else
324 : 0 : gcc_unreachable ();
325 : :
326 : 0 : return NULL_TREE;
327 : : }
328 : :
329 : :
330 : : /* Handle a "pure" attribute; arguments as in
331 : : struct attribute_spec.handler. */
332 : :
333 : : static tree
334 : 20 : handle_pure_attribute (tree *node, tree ARG_UNUSED (name),
335 : : tree ARG_UNUSED (args), int ARG_UNUSED (flags),
336 : : bool * ARG_UNUSED (no_add_attrs))
337 : : {
338 : 20 : if (TREE_CODE (*node) == FUNCTION_DECL)
339 : 20 : DECL_PURE_P (*node) = 1;
340 : : else
341 : 0 : gcc_unreachable ();
342 : :
343 : 20 : return NULL_TREE;
344 : : }
345 : :
346 : :
347 : : /* Handle a "no vops" attribute; arguments as in
348 : : struct attribute_spec.handler. */
349 : :
350 : : static tree
351 : 0 : handle_novops_attribute (tree *node, tree ARG_UNUSED (name),
352 : : tree ARG_UNUSED (args), int ARG_UNUSED (flags),
353 : : bool *ARG_UNUSED (no_add_attrs))
354 : : {
355 : 0 : gcc_assert (TREE_CODE (*node) == FUNCTION_DECL);
356 : 0 : DECL_IS_NOVOPS (*node) = 1;
357 : 0 : return NULL_TREE;
358 : : }
359 : :
360 : :
361 : : /* Helper for nonnull attribute handling; fetch the operand number
362 : : from the attribute argument list. */
363 : :
364 : : static bool
365 : 5 : get_nonnull_operand (tree arg_num_expr, unsigned HOST_WIDE_INT *valp)
366 : : {
367 : : /* Verify the arg number is a constant. */
368 : 5 : if (!tree_fits_uhwi_p (arg_num_expr))
369 : : return false;
370 : :
371 : 5 : *valp = TREE_INT_CST_LOW (arg_num_expr);
372 : 5 : return true;
373 : : }
374 : :
375 : : /* Handle the "nonnull" attribute. */
376 : :
377 : : static tree
378 : 105 : handle_nonnull_attribute (tree *node, tree ARG_UNUSED (name),
379 : : tree args, int ARG_UNUSED (flags),
380 : : bool * ARG_UNUSED (no_add_attrs))
381 : : {
382 : 105 : tree type = *node;
383 : :
384 : : /* If no arguments are specified, all pointer arguments should be
385 : : non-null. Verify a full prototype is given so that the arguments
386 : : will have the correct types when we actually check them later.
387 : : Avoid diagnosing type-generic built-ins since those have no
388 : : prototype. */
389 : 105 : if (!args)
390 : : {
391 : 100 : gcc_assert (prototype_p (type)
392 : : || !TYPE_ATTRIBUTES (type)
393 : : || lookup_attribute ("type generic", TYPE_ATTRIBUTES (type)));
394 : :
395 : 100 : return NULL_TREE;
396 : : }
397 : :
398 : : /* Argument list specified. Verify that each argument number references
399 : : a pointer argument. */
400 : 10 : for (; args; args = TREE_CHAIN (args))
401 : : {
402 : 5 : tree argument;
403 : 5 : unsigned HOST_WIDE_INT arg_num = 0, ck_num;
404 : :
405 : 5 : if (!get_nonnull_operand (TREE_VALUE (args), &arg_num))
406 : 0 : gcc_unreachable ();
407 : :
408 : 5 : argument = TYPE_ARG_TYPES (type);
409 : 5 : if (argument)
410 : : {
411 : 0 : for (ck_num = 1; ; ck_num++)
412 : : {
413 : 5 : if (!argument || ck_num == arg_num)
414 : : break;
415 : 0 : argument = TREE_CHAIN (argument);
416 : : }
417 : :
418 : 5 : gcc_assert (argument
419 : : && TREE_CODE (TREE_VALUE (argument)) == POINTER_TYPE);
420 : : }
421 : : }
422 : :
423 : : return NULL_TREE;
424 : : }
425 : :
426 : :
427 : : /* Handle a "nothrow" attribute; arguments as in
428 : : struct attribute_spec.handler. */
429 : :
430 : : static tree
431 : 4782 : handle_nothrow_attribute (tree *node, tree ARG_UNUSED (name),
432 : : tree ARG_UNUSED (args), int ARG_UNUSED (flags),
433 : : bool * ARG_UNUSED (no_add_attrs))
434 : : {
435 : 4782 : if (TREE_CODE (*node) == FUNCTION_DECL)
436 : 4782 : TREE_NOTHROW (*node) = 1;
437 : : else
438 : 0 : gcc_unreachable ();
439 : :
440 : 4782 : return NULL_TREE;
441 : : }
442 : :
443 : :
444 : : /* Handle a "sentinel" attribute. */
445 : :
446 : : static tree
447 : 0 : handle_sentinel_attribute (tree *node, tree ARG_UNUSED (name), tree args,
448 : : int ARG_UNUSED (flags),
449 : : bool * ARG_UNUSED (no_add_attrs))
450 : : {
451 : 0 : gcc_assert (stdarg_p (*node));
452 : :
453 : 0 : if (args)
454 : : {
455 : 0 : tree position = TREE_VALUE (args);
456 : 0 : gcc_assert (TREE_CODE (position) == INTEGER_CST);
457 : 0 : if (tree_int_cst_lt (position, integer_zero_node))
458 : 0 : gcc_unreachable ();
459 : : }
460 : :
461 : 0 : return NULL_TREE;
462 : : }
463 : :
464 : : /* Handle a "type_generic" attribute. */
465 : :
466 : : static tree
467 : 45 : handle_type_generic_attribute (tree *node, tree ARG_UNUSED (name),
468 : : tree ARG_UNUSED (args), int ARG_UNUSED (flags),
469 : : bool * ARG_UNUSED (no_add_attrs))
470 : : {
471 : : /* Ensure we have a function type. */
472 : 45 : gcc_assert (TREE_CODE (*node) == FUNCTION_TYPE);
473 : :
474 : : /* Ensure we have a variadic function. */
475 : 45 : gcc_assert (!prototype_p (*node) || stdarg_p (*node));
476 : :
477 : 45 : return NULL_TREE;
478 : : }
479 : :
480 : : /* Handle a "transaction_pure" attribute. */
481 : :
482 : : static tree
483 : 0 : handle_transaction_pure_attribute (tree *node, tree ARG_UNUSED (name),
484 : : tree ARG_UNUSED (args),
485 : : int ARG_UNUSED (flags),
486 : : bool * ARG_UNUSED (no_add_attrs))
487 : : {
488 : : /* Ensure we have a function type. */
489 : 0 : gcc_assert (TREE_CODE (*node) == FUNCTION_TYPE);
490 : :
491 : 0 : return NULL_TREE;
492 : : }
493 : :
494 : : /* Handle a "returns_twice" attribute. */
495 : :
496 : : static tree
497 : 0 : handle_returns_twice_attribute (tree *node, tree ARG_UNUSED (name),
498 : : tree ARG_UNUSED (args),
499 : : int ARG_UNUSED (flags),
500 : : bool * ARG_UNUSED (no_add_attrs))
501 : : {
502 : 0 : gcc_assert (TREE_CODE (*node) == FUNCTION_DECL);
503 : :
504 : 0 : DECL_IS_RETURNS_TWICE (*node) = 1;
505 : :
506 : 0 : return NULL_TREE;
507 : : }
508 : :
509 : : static tree
510 : 0 : handle_patchable_function_entry_attribute (tree *, tree, tree, int, bool *)
511 : : {
512 : : /* Nothing to be done here. */
513 : 0 : return NULL_TREE;
514 : : }
515 : :
516 : : /* Ignore the given attribute. Used when this attribute may be usefully
517 : : overridden by the target, but is not used generically. */
518 : :
519 : : static tree
520 : 0 : ignore_attribute (tree * ARG_UNUSED (node), tree ARG_UNUSED (name),
521 : : tree ARG_UNUSED (args), int ARG_UNUSED (flags),
522 : : bool *no_add_attrs)
523 : : {
524 : 0 : *no_add_attrs = true;
525 : 0 : return NULL_TREE;
526 : : }
527 : :
528 : : /* Handle a "format" attribute; arguments as in
529 : : struct attribute_spec.handler. */
530 : :
531 : : static tree
532 : 0 : handle_format_attribute (tree * ARG_UNUSED (node), tree ARG_UNUSED (name),
533 : : tree ARG_UNUSED (args), int ARG_UNUSED (flags),
534 : : bool *no_add_attrs)
535 : : {
536 : 0 : *no_add_attrs = true;
537 : 0 : return NULL_TREE;
538 : : }
539 : :
540 : :
541 : : /* Handle a "format_arg" attribute; arguments as in
542 : : struct attribute_spec.handler. */
543 : :
544 : : tree
545 : 0 : handle_format_arg_attribute (tree * ARG_UNUSED (node), tree ARG_UNUSED (name),
546 : : tree ARG_UNUSED (args), int ARG_UNUSED (flags),
547 : : bool *no_add_attrs)
548 : : {
549 : 0 : *no_add_attrs = true;
550 : 0 : return NULL_TREE;
551 : : }
552 : :
553 : :
554 : : /* Handle a "fn spec" attribute; arguments as in
555 : : struct attribute_spec.handler. */
556 : :
557 : : static tree
558 : 0 : handle_fnspec_attribute (tree *node ATTRIBUTE_UNUSED, tree ARG_UNUSED (name),
559 : : tree args, int ARG_UNUSED (flags),
560 : : bool *no_add_attrs ATTRIBUTE_UNUSED)
561 : : {
562 : 0 : gcc_assert (args
563 : : && TREE_CODE (TREE_VALUE (args)) == STRING_CST
564 : : && !TREE_CHAIN (args));
565 : 0 : return NULL_TREE;
566 : : }
567 : :
568 : : /* Handle an "visibility" attribute; arguments as in
569 : : struct attribute_spec.handler. */
570 : :
571 : : static tree
572 : 5 : handle_visibility_attribute (tree *node, tree name, tree args,
573 : : int ARG_UNUSED (flags),
574 : : bool *ARG_UNUSED (no_add_attrs))
575 : : {
576 : 5 : tree decl = *node;
577 : 5 : tree id = TREE_VALUE (args);
578 : 5 : enum symbol_visibility vis;
579 : :
580 : 5 : if (TYPE_P (*node))
581 : : {
582 : 0 : if (TREE_CODE (*node) == ENUMERAL_TYPE)
583 : : /* OK. */;
584 : 0 : else if (!RECORD_OR_UNION_TYPE_P (*node))
585 : : {
586 : 0 : warning (OPT_Wattributes, "%qE attribute ignored on non-class types",
587 : : name);
588 : 0 : return NULL_TREE;
589 : : }
590 : 0 : else if (TYPE_FIELDS (*node))
591 : : {
592 : 0 : error ("%qE attribute ignored because %qT is already defined",
593 : : name, *node);
594 : 0 : return NULL_TREE;
595 : : }
596 : : }
597 : 5 : else if (decl_function_context (decl) != 0 || !TREE_PUBLIC (decl))
598 : : {
599 : 0 : warning (OPT_Wattributes, "%qE attribute ignored", name);
600 : 0 : return NULL_TREE;
601 : : }
602 : :
603 : 5 : if (TREE_CODE (id) != STRING_CST)
604 : : {
605 : 0 : error ("visibility argument not a string");
606 : 0 : return NULL_TREE;
607 : : }
608 : :
609 : : /* If this is a type, set the visibility on the type decl. */
610 : 5 : if (TYPE_P (decl))
611 : : {
612 : 0 : decl = TYPE_NAME (decl);
613 : 0 : if (!decl)
614 : : return NULL_TREE;
615 : 0 : if (TREE_CODE (decl) == IDENTIFIER_NODE)
616 : : {
617 : 0 : warning (OPT_Wattributes, "%qE attribute ignored on types",
618 : : name);
619 : 0 : return NULL_TREE;
620 : : }
621 : : }
622 : :
623 : 5 : if (strcmp (TREE_STRING_POINTER (id), "default") == 0)
624 : : vis = VISIBILITY_DEFAULT;
625 : 5 : else if (strcmp (TREE_STRING_POINTER (id), "internal") == 0)
626 : : vis = VISIBILITY_INTERNAL;
627 : 5 : else if (strcmp (TREE_STRING_POINTER (id), "hidden") == 0)
628 : : vis = VISIBILITY_HIDDEN;
629 : 0 : else if (strcmp (TREE_STRING_POINTER (id), "protected") == 0)
630 : : vis = VISIBILITY_PROTECTED;
631 : : else
632 : : {
633 : 0 : error ("attribute %qE argument must be one of %qs, %qs, %qs, or %qs",
634 : : name, "default", "hidden", "protected", "internal");
635 : 0 : vis = VISIBILITY_DEFAULT;
636 : : }
637 : :
638 : 5 : if (DECL_VISIBILITY_SPECIFIED (decl)
639 : 5 : && vis != DECL_VISIBILITY (decl))
640 : : {
641 : 0 : tree attributes = (TYPE_P (*node)
642 : 0 : ? TYPE_ATTRIBUTES (*node)
643 : 0 : : DECL_ATTRIBUTES (decl));
644 : 0 : if (lookup_attribute ("visibility", attributes))
645 : 0 : error ("%qD redeclared with different visibility", decl);
646 : : else if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
647 : : && lookup_attribute ("dllimport", attributes))
648 : : error ("%qD was declared %qs which implies default visibility",
649 : : decl, "dllimport");
650 : : else if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
651 : : && lookup_attribute ("dllexport", attributes))
652 : : error ("%qD was declared %qs which implies default visibility",
653 : : decl, "dllexport");
654 : : }
655 : :
656 : 5 : DECL_VISIBILITY (decl) = vis;
657 : 5 : DECL_VISIBILITY_SPECIFIED (decl) = 1;
658 : :
659 : : /* Go ahead and attach the attribute to the node as well. This is needed
660 : : so we can determine whether we have VISIBILITY_DEFAULT because the
661 : : visibility was not specified, or because it was explicitly overridden
662 : : from the containing scope. */
663 : :
664 : 5 : return NULL_TREE;
665 : : }
666 : :
667 : : /* Handle a "always_inline" attribute; arguments as in
668 : : struct attribute_spec.handler. */
669 : :
670 : : static tree
671 : 20 : handle_always_inline_attribute (tree *node, tree name,
672 : : tree ARG_UNUSED (args),
673 : : int ARG_UNUSED (flags),
674 : : bool *no_add_attrs)
675 : : {
676 : 20 : if (TREE_CODE (*node) == FUNCTION_DECL)
677 : : {
678 : : /* Set the attribute and mark it for disregarding inline
679 : : limits. */
680 : 20 : DECL_DISREGARD_INLINE_LIMITS (*node) = 1;
681 : : }
682 : : else
683 : : {
684 : 0 : warning (OPT_Wattributes, "%qE attribute ignored", name);
685 : 0 : *no_add_attrs = true;
686 : : }
687 : :
688 : 20 : return NULL_TREE;
689 : : }
690 : :
691 : : /* Handle a "cold" and attribute; arguments as in
692 : : struct attribute_spec.handler. */
693 : :
694 : : static tree
695 : 1153 : handle_cold_attribute (tree *node, tree name, tree ARG_UNUSED (args),
696 : : int ARG_UNUSED (flags), bool *no_add_attrs)
697 : : {
698 : 1153 : if (TREE_CODE (*node) == FUNCTION_DECL
699 : 1153 : || TREE_CODE (*node) == LABEL_DECL)
700 : : {
701 : : /* Attribute cold processing is done later with lookup_attribute. */
702 : : }
703 : : else
704 : : {
705 : 0 : warning (OPT_Wattributes, "%qE attribute ignored", name);
706 : 0 : *no_add_attrs = true;
707 : : }
708 : :
709 : 1153 : return NULL_TREE;
710 : : }
711 : :
712 : : /* Handle a "noinline" attribute; arguments as in
713 : : struct attribute_spec.handler. */
714 : :
715 : : static tree
716 : 5 : handle_noinline_attribute (tree *node, tree name,
717 : : tree ARG_UNUSED (args),
718 : : int ARG_UNUSED (flags), bool *no_add_attrs)
719 : : {
720 : 5 : if (TREE_CODE (*node) == FUNCTION_DECL)
721 : 5 : DECL_UNINLINABLE (*node) = 1;
722 : : else
723 : : {
724 : 0 : warning (OPT_Wattributes, "%qE attribute ignored", name);
725 : 0 : *no_add_attrs = true;
726 : : }
727 : :
728 : 5 : return NULL_TREE;
729 : : }
730 : :
731 : : /* Handle a "weak" attribute; arguments as in
732 : : struct attribute_spec.handler. */
733 : :
734 : : static tree
735 : 5 : handle_weak_attribute (tree *node, tree name,
736 : : tree ARG_UNUSED (args),
737 : : int ARG_UNUSED (flags),
738 : : bool * ARG_UNUSED (no_add_attrs))
739 : : {
740 : 5 : if (TREE_CODE (*node) == FUNCTION_DECL
741 : 5 : && DECL_DECLARED_INLINE_P (*node))
742 : : {
743 : 0 : warning (OPT_Wattributes, "inline function %q+D declared weak", *node);
744 : 0 : *no_add_attrs = true;
745 : : }
746 : 5 : else if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (*node)))
747 : : {
748 : 0 : error ("indirect function %q+D cannot be declared weak", *node);
749 : 0 : *no_add_attrs = true;
750 : 0 : return NULL_TREE;
751 : : }
752 : 5 : else if (VAR_OR_FUNCTION_DECL_P (*node))
753 : 5 : declare_weak (*node);
754 : : else
755 : 0 : warning (OPT_Wattributes, "%qE attribute ignored", name);
756 : :
757 : : return NULL_TREE;
758 : : }
759 : :
760 : : /* Handle a "target" attribute. */
761 : :
762 : : static tree
763 : 0 : handle_target_attribute (tree *node, tree name, tree args, int flags,
764 : : bool *no_add_attrs)
765 : : {
766 : : /* Ensure we have a function declaration. */
767 : 0 : if (TREE_CODE (*node) != FUNCTION_DECL)
768 : : {
769 : 0 : warning (OPT_Wattributes, "%qE attribute ignored", name);
770 : 0 : *no_add_attrs = true;
771 : : }
772 : 0 : else if (! targetm.target_option.valid_attribute_p (*node, name, args,
773 : : flags))
774 : 0 : *no_add_attrs = true;
775 : :
776 : : /* Check that there's no empty string in values of the attribute. */
777 : 0 : for (tree t = args; t != NULL_TREE; t = TREE_CHAIN (t))
778 : : {
779 : 0 : tree value = TREE_VALUE (t);
780 : 0 : if (TREE_CODE (value) == STRING_CST
781 : 0 : && TREE_STRING_LENGTH (value) == 1
782 : 0 : && TREE_STRING_POINTER (value)[0] == '\0')
783 : : {
784 : 0 : warning (OPT_Wattributes, "empty string in attribute %<target%>");
785 : 0 : *no_add_attrs = true;
786 : : }
787 : : }
788 : :
789 : 0 : return NULL_TREE;
790 : : }
791 : :
792 : : /* Handle a "used" attribute; arguments as in
793 : : struct attribute_spec.handler. */
794 : :
795 : : static tree
796 : 5 : handle_used_attribute (tree *pnode, tree name, tree ARG_UNUSED (args),
797 : : int ARG_UNUSED (flags), bool *no_add_attrs)
798 : : {
799 : 5 : tree node = *pnode;
800 : :
801 : 5 : if (TREE_CODE (node) == FUNCTION_DECL
802 : 0 : || (VAR_P (node) && TREE_STATIC (node))
803 : 0 : || (TREE_CODE (node) == TYPE_DECL))
804 : : {
805 : 5 : TREE_USED (node) = 1;
806 : 5 : DECL_PRESERVE_P (node) = 1;
807 : 5 : if (VAR_P (node))
808 : 0 : DECL_READ_P (node) = 1;
809 : : }
810 : : else
811 : : {
812 : 0 : warning (OPT_Wattributes, "%qE attribute ignored", name);
813 : 0 : *no_add_attrs = true;
814 : : }
815 : :
816 : 5 : return NULL_TREE;
817 : : }
818 : :
819 : : /* Handle an "alias" or "ifunc" attribute; arguments as in
820 : : struct attribute_spec.handler, except that IS_ALIAS tells us
821 : : whether this is an alias as opposed to ifunc attribute. */
822 : :
823 : : static tree
824 : 5 : handle_alias_ifunc_attribute (bool is_alias, tree *node, tree name, tree args,
825 : : bool *no_add_attrs)
826 : : {
827 : 5 : tree decl = *node;
828 : :
829 : 5 : if (TREE_CODE (decl) != FUNCTION_DECL
830 : 0 : && (!is_alias || !VAR_P (decl)))
831 : : {
832 : 0 : warning (OPT_Wattributes, "%qE attribute ignored", name);
833 : 0 : *no_add_attrs = true;
834 : : }
835 : 5 : else if ((TREE_CODE (decl) == FUNCTION_DECL && DECL_INITIAL (decl))
836 : 5 : || (TREE_CODE (decl) != FUNCTION_DECL
837 : 0 : && TREE_PUBLIC (decl) && !DECL_EXTERNAL (decl))
838 : : /* A static variable declaration is always a tentative definition,
839 : : but the alias is a non-tentative definition which overrides. */
840 : 10 : || (TREE_CODE (decl) != FUNCTION_DECL
841 : 0 : && ! TREE_PUBLIC (decl) && DECL_INITIAL (decl)))
842 : : {
843 : 0 : error ("%q+D defined both normally and as %qE attribute", decl, name);
844 : 0 : *no_add_attrs = true;
845 : 0 : return NULL_TREE;
846 : : }
847 : 5 : else if (!is_alias
848 : 5 : && (lookup_attribute ("weak", DECL_ATTRIBUTES (decl))
849 : 0 : || lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))))
850 : : {
851 : 0 : error ("weak %q+D cannot be defined %qE", decl, name);
852 : 0 : *no_add_attrs = true;
853 : 0 : return NULL_TREE;
854 : : }
855 : :
856 : : /* Note that the very first time we process a nested declaration,
857 : : decl_function_context will not be set. Indeed, *would* never
858 : : be set except for the DECL_INITIAL/DECL_EXTERNAL frobbery that
859 : : we do below. After such frobbery, pushdecl would set the context.
860 : : In any case, this is never what we want. */
861 : 5 : else if (decl_function_context (decl) == 0 && current_function_decl == NULL)
862 : : {
863 : 5 : tree id;
864 : :
865 : 5 : id = TREE_VALUE (args);
866 : 5 : if (TREE_CODE (id) != STRING_CST)
867 : : {
868 : 0 : error ("attribute %qE argument not a string", name);
869 : 0 : *no_add_attrs = true;
870 : 0 : return NULL_TREE;
871 : : }
872 : 5 : id = get_identifier (TREE_STRING_POINTER (id));
873 : : /* This counts as a use of the object pointed to. */
874 : 5 : TREE_USED (id) = 1;
875 : :
876 : 5 : if (TREE_CODE (decl) == FUNCTION_DECL)
877 : 5 : DECL_INITIAL (decl) = error_mark_node;
878 : : else
879 : 0 : TREE_STATIC (decl) = 1;
880 : :
881 : 5 : if (!is_alias)
882 : : {
883 : : /* ifuncs are also aliases, so set that attribute too. */
884 : 0 : DECL_ATTRIBUTES (decl)
885 : 0 : = tree_cons (get_identifier ("alias"), args,
886 : 0 : DECL_ATTRIBUTES (decl));
887 : 0 : DECL_ATTRIBUTES (decl) = tree_cons (get_identifier ("ifunc"),
888 : 0 : NULL, DECL_ATTRIBUTES (decl));
889 : : }
890 : : }
891 : : else
892 : : {
893 : 0 : warning (OPT_Wattributes, "%qE attribute ignored", name);
894 : 0 : *no_add_attrs = true;
895 : : }
896 : :
897 : 5 : if (decl_in_symtab_p (*node))
898 : : {
899 : 5 : struct symtab_node *n = symtab_node::get (decl);
900 : 5 : if (n && n->refuse_visibility_changes)
901 : 0 : error ("%+qD declared %qs after being used",
902 : : decl, is_alias ? "alias" : "ifunc");
903 : : }
904 : :
905 : :
906 : : return NULL_TREE;
907 : : }
908 : :
909 : : /* Handle an "alias" or "ifunc" attribute; arguments as in
910 : : struct attribute_spec.handler. */
911 : :
912 : : static tree
913 : 5 : handle_alias_attribute (tree *node, tree name, tree args,
914 : : int ARG_UNUSED (flags), bool *no_add_attrs)
915 : : {
916 : 5 : return handle_alias_ifunc_attribute (true, node, name, args, no_add_attrs);
917 : : }
918 : :
919 : : /* (end of attribute-handling). */
920 : :
921 : : /* Language-dependent contents of a type. */
922 : :
923 : : struct GTY(()) lang_type
924 : : {
925 : : char dummy;
926 : : };
927 : :
928 : : /* Language-dependent contents of a decl. */
929 : :
930 : : struct GTY((variable_size)) lang_decl
931 : : {
932 : : char dummy;
933 : : };
934 : :
935 : : /* Language-dependent contents of an identifier. This must include a
936 : : tree_identifier. */
937 : :
938 : : struct GTY(()) lang_identifier
939 : : {
940 : : struct tree_identifier common;
941 : : };
942 : :
943 : : /* The resulting tree type. */
944 : :
945 : : union GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"),
946 : : chain_next ("CODE_CONTAINS_STRUCT (TREE_CODE (&%h.generic), TS_COMMON) ? ((union lang_tree_node *) TREE_CHAIN (&%h.generic)) : NULL")))
947 : : lang_tree_node
948 : : {
949 : : union tree_node GTY((tag ("0"),
950 : : desc ("tree_node_structure (&%h)"))) generic;
951 : : struct lang_identifier GTY((tag ("1"))) identifier;
952 : : };
953 : :
954 : : /* We don't use language_function. */
955 : :
956 : : struct GTY(()) language_function
957 : : {
958 : : int dummy;
959 : : };
960 : :
961 : : /* GC-marking callback for use from jit_root_tab.
962 : :
963 : : If there's an active playback context, call its marking method
964 : : so that it can mark any pointers it references. */
965 : :
966 : 477370 : static void my_ggc_walker (void *)
967 : : {
968 : 477370 : if (gcc::jit::active_playback_ctxt)
969 : 477370 : gcc::jit::active_playback_ctxt->gt_ggc_mx ();
970 : 477370 : }
971 : :
972 : : const char *dummy;
973 : :
974 : : struct ggc_root_tab jit_root_tab[] =
975 : : {
976 : : {
977 : : &dummy, 1, 0, my_ggc_walker, NULL
978 : : },
979 : : LAST_GGC_ROOT_TAB
980 : : };
981 : :
982 : : /* JIT-specific implementation of diagnostic callbacks. */
983 : :
984 : : /* Implementation of "begin_diagnostic". */
985 : :
986 : : static void
987 : 25 : jit_begin_diagnostic (diagnostic_context */*context*/,
988 : : const diagnostic_info */*diagnostic*/)
989 : : {
990 : 25 : gcc_assert (gcc::jit::active_playback_ctxt);
991 : 25 : JIT_LOG_SCOPE (gcc::jit::active_playback_ctxt->get_logger ());
992 : :
993 : : /* No-op (apart from logging); the real error-handling is done in the
994 : : "end_diagnostic" hook. */
995 : 25 : }
996 : :
997 : : /* Implementation of "end_diagnostic". */
998 : :
999 : : static void
1000 : 25 : jit_end_diagnostic (diagnostic_context *context,
1001 : : const diagnostic_info *diagnostic,
1002 : : diagnostic_t)
1003 : : {
1004 : 25 : gcc_assert (gcc::jit::active_playback_ctxt);
1005 : 25 : JIT_LOG_SCOPE (gcc::jit::active_playback_ctxt->get_logger ());
1006 : :
1007 : : /* Delegate to the playback context (and thence to the
1008 : : recording context). */
1009 : 25 : gcc_assert (diagnostic);
1010 : 25 : gcc::jit::active_playback_ctxt->add_diagnostic (context, *diagnostic);
1011 : 25 : }
1012 : :
1013 : : /* Language hooks. */
1014 : :
1015 : : static bool
1016 : 1178 : jit_langhook_init (void)
1017 : : {
1018 : 1178 : gcc_assert (gcc::jit::active_playback_ctxt);
1019 : 1178 : JIT_LOG_SCOPE (gcc::jit::active_playback_ctxt->get_logger ());
1020 : :
1021 : 1178 : static bool registered_root_tab = false;
1022 : 1178 : if (!registered_root_tab)
1023 : : {
1024 : 114 : ggc_register_root_tab (jit_root_tab);
1025 : 114 : registered_root_tab = true;
1026 : : }
1027 : :
1028 : 1178 : gcc_assert (global_dc);
1029 : 1178 : diagnostic_starter (global_dc) = jit_begin_diagnostic;
1030 : 1178 : diagnostic_finalizer (global_dc) = jit_end_diagnostic;
1031 : :
1032 : 1178 : build_common_tree_nodes (false);
1033 : :
1034 : 1178 : build_common_builtin_nodes ();
1035 : :
1036 : : /* The default precision for floating point numbers. This is used
1037 : : for floating point constants with abstract type. This may
1038 : : eventually be controllable by a command line option. */
1039 : 1178 : mpfr_set_default_prec (256);
1040 : :
1041 : 2356 : return true;
1042 : 1178 : }
1043 : :
1044 : : static void
1045 : 1178 : jit_langhook_parse_file (void)
1046 : : {
1047 : : /* Replay the activity by the client, recorded on the context. */
1048 : 1178 : gcc_assert (gcc::jit::active_playback_ctxt);
1049 : 1178 : gcc::jit::active_playback_ctxt->replay ();
1050 : 1178 : }
1051 : :
1052 : : static tree
1053 : 12149 : jit_langhook_type_for_mode (machine_mode mode, int unsignedp)
1054 : : {
1055 : : /* Build any vector types here (see PR 46805). */
1056 : 12149 : if (VECTOR_MODE_P (mode))
1057 : : {
1058 : 240 : tree inner;
1059 : :
1060 : 480 : inner = jit_langhook_type_for_mode (GET_MODE_INNER (mode), unsignedp);
1061 : 240 : if (inner != NULL_TREE)
1062 : 240 : return build_vector_type_for_mode (inner, mode);
1063 : : return NULL_TREE;
1064 : : }
1065 : :
1066 : 11909 : if (mode == TYPE_MODE (float_type_node))
1067 : 140 : return float_type_node;
1068 : :
1069 : 11769 : if (mode == TYPE_MODE (double_type_node))
1070 : 339 : return double_type_node;
1071 : :
1072 : 11430 : if (mode == TYPE_MODE (intQI_type_node))
1073 : 790 : return unsignedp ? unsigned_intQI_type_node : intQI_type_node;
1074 : 10640 : if (mode == TYPE_MODE (intHI_type_node))
1075 : 60 : return unsignedp ? unsigned_intHI_type_node : intHI_type_node;
1076 : 10580 : if (mode == TYPE_MODE (intSI_type_node))
1077 : 1449 : return unsignedp ? unsigned_intSI_type_node : intSI_type_node;
1078 : 9131 : if (mode == TYPE_MODE (intDI_type_node))
1079 : 2063 : return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
1080 : 7068 : if (mode == TYPE_MODE (intTI_type_node))
1081 : 0 : return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
1082 : :
1083 : 7068 : if (mode == TYPE_MODE (integer_type_node))
1084 : 0 : return unsignedp ? unsigned_type_node : integer_type_node;
1085 : :
1086 : 7068 : if (mode == TYPE_MODE (long_integer_type_node))
1087 : 0 : return unsignedp ? long_unsigned_type_node : long_integer_type_node;
1088 : :
1089 : 7068 : if (mode == TYPE_MODE (long_long_integer_type_node))
1090 : 0 : return unsignedp ? long_long_unsigned_type_node : long_long_integer_type_node;
1091 : :
1092 : 7068 : if (COMPLEX_MODE_P (mode))
1093 : : {
1094 : 7068 : if (mode == TYPE_MODE (complex_float_type_node))
1095 : 1178 : return complex_float_type_node;
1096 : 5890 : if (mode == TYPE_MODE (complex_double_type_node))
1097 : 1178 : return complex_double_type_node;
1098 : 4712 : if (mode == TYPE_MODE (complex_long_double_type_node))
1099 : 1178 : return complex_long_double_type_node;
1100 : 3534 : if (mode == TYPE_MODE (complex_integer_type_node) && !unsignedp)
1101 : 0 : return complex_integer_type_node;
1102 : : }
1103 : :
1104 : : /* gcc_unreachable */
1105 : : return NULL;
1106 : : }
1107 : :
1108 : : /* Record a builtin function. We just ignore builtin functions. */
1109 : :
1110 : : static tree
1111 : 48298 : jit_langhook_builtin_function (tree decl)
1112 : : {
1113 : 48298 : return decl;
1114 : : }
1115 : :
1116 : : static bool
1117 : 60 : jit_langhook_global_bindings_p (void)
1118 : : {
1119 : 60 : return true;
1120 : : }
1121 : :
1122 : : static tree
1123 : 0 : jit_langhook_pushdecl (tree decl ATTRIBUTE_UNUSED)
1124 : : {
1125 : 0 : gcc_unreachable ();
1126 : : }
1127 : :
1128 : : static tree
1129 : 0 : jit_langhook_getdecls (void)
1130 : : {
1131 : 0 : return NULL;
1132 : : }
1133 : :
1134 : : #undef LANG_HOOKS_NAME
1135 : : #define LANG_HOOKS_NAME "libgccjit"
1136 : :
1137 : : #undef LANG_HOOKS_INIT
1138 : : #define LANG_HOOKS_INIT jit_langhook_init
1139 : :
1140 : : #undef LANG_HOOKS_PARSE_FILE
1141 : : #define LANG_HOOKS_PARSE_FILE jit_langhook_parse_file
1142 : :
1143 : : #undef LANG_HOOKS_TYPE_FOR_MODE
1144 : : #define LANG_HOOKS_TYPE_FOR_MODE jit_langhook_type_for_mode
1145 : :
1146 : : #undef LANG_HOOKS_BUILTIN_FUNCTION
1147 : : #define LANG_HOOKS_BUILTIN_FUNCTION jit_langhook_builtin_function
1148 : :
1149 : : #undef LANG_HOOKS_GLOBAL_BINDINGS_P
1150 : : #define LANG_HOOKS_GLOBAL_BINDINGS_P jit_langhook_global_bindings_p
1151 : :
1152 : : #undef LANG_HOOKS_PUSHDECL
1153 : : #define LANG_HOOKS_PUSHDECL jit_langhook_pushdecl
1154 : :
1155 : : #undef LANG_HOOKS_GETDECLS
1156 : : #define LANG_HOOKS_GETDECLS jit_langhook_getdecls
1157 : :
1158 : : /* Attribute hooks. */
1159 : : #undef LANG_HOOKS_ATTRIBUTE_TABLE
1160 : : #define LANG_HOOKS_ATTRIBUTE_TABLE jit_attribute_table
1161 : :
1162 : : #undef LANG_HOOKS_DEEP_UNSHARING
1163 : : #define LANG_HOOKS_DEEP_UNSHARING true
1164 : :
1165 : : struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
1166 : :
1167 : : #include "gt-jit-dummy-frontend.h"
1168 : : #include "gtype-jit.h"
|