xfail scan-tree-dump-not throw in g++.dg/pr99966.C on hppa*64*-*-*
[official-gcc.git] / gcc / jit / dummy-frontend.cc
blobdbeeacd17a86bf01b5cc1ca719bf0fb516fd89d5
1 /* jit.c -- Dummy "frontend" for use during JIT-compilation.
2 Copyright (C) 2013-2024 Free Software Foundation, Inc.
4 This file is part of GCC.
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.
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.
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/>. */
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"
35 #include <mpfr.h>
37 /* Attribute handling. */
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 *) ;
67 static tree ignore_attribute (tree *, tree, tree, int, bool *);
69 /* Helper to define attribute exclusions. */
70 #define ATTR_EXCL(name, function, type, variable) \
71 { name, function, type, variable }
73 /* Define attributes that are mutually exclusive with one another. */
74 static const struct attribute_spec::exclusions attr_noreturn_exclusions[] =
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),
86 static const struct attribute_spec::exclusions attr_returns_twice_exclusions[] =
88 ATTR_EXCL ("noreturn", true, true, true),
89 ATTR_EXCL (NULL, false, false, false),
92 /* Exclusions that apply to attribute alloc_align, alloc_size, and malloc. */
93 static const struct attribute_spec::exclusions attr_alloc_exclusions[] =
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),
101 static const struct attribute_spec::exclusions attr_const_pure_exclusions[] =
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)
112 static const struct attribute_spec::exclusions attr_always_inline_exclusions[] =
114 ATTR_EXCL ("noinline", true, true, true),
115 ATTR_EXCL ("target_clones", true, true, true),
116 ATTR_EXCL (NULL, false, false, false),
119 extern const struct attribute_spec::exclusions attr_cold_hot_exclusions[] =
121 ATTR_EXCL ("cold", true, true, true),
122 ATTR_EXCL ("hot", true, true, true),
123 ATTR_EXCL (NULL, false, false, false)
126 static const struct attribute_spec::exclusions attr_noinline_exclusions[] =
128 ATTR_EXCL ("always_inline", true, true, true),
129 ATTR_EXCL ("gnu_inline", true, true, true),
130 ATTR_EXCL (NULL, false, false, false),
133 static const struct attribute_spec::exclusions attr_target_exclusions[] =
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),
140 /* Table of machine-independent attributes supported in libgccjit. */
141 static const attribute_spec jit_gnu_attributes[] =
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 },
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 },
205 static const scoped_attribute_specs jit_gnu_attribute_table =
207 "gnu", { jit_gnu_attributes }
210 /* Give the specifications for the format attributes, used by C and all
211 descendants. */
213 static const attribute_spec jit_format_attributes[] =
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 }
223 static const scoped_attribute_specs jit_format_attribute_table =
225 "gnu", { jit_format_attributes }
228 static const scoped_attribute_specs *const jit_attribute_table[] =
230 &jit_gnu_attribute_table,
231 &jit_format_attribute_table
234 /* Attribute handlers. */
236 /* Handle a "noreturn" attribute; arguments as in
237 struct attribute_spec.handler. */
239 static tree
240 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))
244 tree type = TREE_TYPE (*node);
246 if (TREE_CODE (*node) == FUNCTION_DECL)
247 TREE_THIS_VOLATILE (*node) = 1;
248 else if (TREE_CODE (type) == POINTER_TYPE
249 && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
250 TREE_TYPE (*node)
251 = build_pointer_type
252 (build_type_variant (TREE_TYPE (type),
253 TYPE_READONLY (TREE_TYPE (type)), 1));
254 else
255 gcc_unreachable ();
257 return NULL_TREE;
260 /* Handle a "leaf" attribute; arguments as in
261 struct attribute_spec.handler. */
263 static tree
264 handle_leaf_attribute (tree *node, tree name,
265 tree ARG_UNUSED (args),
266 int ARG_UNUSED (flags), bool *no_add_attrs)
268 if (TREE_CODE (*node) != FUNCTION_DECL)
270 warning (OPT_Wattributes, "%qE attribute ignored", name);
271 *no_add_attrs = true;
273 if (!TREE_PUBLIC (*node))
275 warning (OPT_Wattributes, "%qE attribute has no effect on unit local functions", name);
276 *no_add_attrs = true;
279 return NULL_TREE;
282 /* Handle a "const" attribute; arguments as in
283 struct attribute_spec.handler. */
285 static tree
286 handle_const_attribute (tree *node, tree name, tree ARG_UNUSED (args),
287 int ARG_UNUSED (flags), bool *no_add_attrs)
289 tree type = TREE_TYPE (*node);
291 /* See FIXME comment on noreturn in c_common_attribute_table. */
292 if (TREE_CODE (*node) == FUNCTION_DECL)
293 TREE_READONLY (*node) = 1;
294 else if (TREE_CODE (type) == POINTER_TYPE
295 && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
296 TREE_TYPE (*node)
297 = (build_qualified_type
298 (build_pointer_type
299 (build_type_variant (TREE_TYPE (type), 1,
300 TREE_THIS_VOLATILE (TREE_TYPE (type)))),
301 TYPE_QUALS (type)));
302 else
304 warning (OPT_Wattributes, "%qE attribute ignored", name);
305 *no_add_attrs = true;
308 return NULL_TREE;
312 /* Handle a "malloc" attribute; arguments as in
313 struct attribute_spec.handler. */
315 static tree
316 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))
320 if (TREE_CODE (*node) == FUNCTION_DECL
321 && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (*node))))
322 DECL_IS_MALLOC (*node) = 1;
323 else
324 gcc_unreachable ();
326 return NULL_TREE;
330 /* Handle a "pure" attribute; arguments as in
331 struct attribute_spec.handler. */
333 static tree
334 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))
338 if (TREE_CODE (*node) == FUNCTION_DECL)
339 DECL_PURE_P (*node) = 1;
340 else
341 gcc_unreachable ();
343 return NULL_TREE;
347 /* Handle a "no vops" attribute; arguments as in
348 struct attribute_spec.handler. */
350 static tree
351 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))
355 gcc_assert (TREE_CODE (*node) == FUNCTION_DECL);
356 DECL_IS_NOVOPS (*node) = 1;
357 return NULL_TREE;
361 /* Helper for nonnull attribute handling; fetch the operand number
362 from the attribute argument list. */
364 static bool
365 get_nonnull_operand (tree arg_num_expr, unsigned HOST_WIDE_INT *valp)
367 /* Verify the arg number is a constant. */
368 if (!tree_fits_uhwi_p (arg_num_expr))
369 return false;
371 *valp = TREE_INT_CST_LOW (arg_num_expr);
372 return true;
375 /* Handle the "nonnull" attribute. */
377 static tree
378 handle_nonnull_attribute (tree *node, tree ARG_UNUSED (name),
379 tree args, int ARG_UNUSED (flags),
380 bool * ARG_UNUSED (no_add_attrs))
382 tree type = *node;
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 if (!args)
391 gcc_assert (prototype_p (type)
392 || !TYPE_ATTRIBUTES (type)
393 || lookup_attribute ("type generic", TYPE_ATTRIBUTES (type)));
395 return NULL_TREE;
398 /* Argument list specified. Verify that each argument number references
399 a pointer argument. */
400 for (; args; args = TREE_CHAIN (args))
402 tree argument;
403 unsigned HOST_WIDE_INT arg_num = 0, ck_num;
405 if (!get_nonnull_operand (TREE_VALUE (args), &arg_num))
406 gcc_unreachable ();
408 argument = TYPE_ARG_TYPES (type);
409 if (argument)
411 for (ck_num = 1; ; ck_num++)
413 if (!argument || ck_num == arg_num)
414 break;
415 argument = TREE_CHAIN (argument);
418 gcc_assert (argument
419 && TREE_CODE (TREE_VALUE (argument)) == POINTER_TYPE);
423 return NULL_TREE;
427 /* Handle a "nothrow" attribute; arguments as in
428 struct attribute_spec.handler. */
430 static tree
431 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))
435 if (TREE_CODE (*node) == FUNCTION_DECL)
436 TREE_NOTHROW (*node) = 1;
437 else
438 gcc_unreachable ();
440 return NULL_TREE;
444 /* Handle a "sentinel" attribute. */
446 static tree
447 handle_sentinel_attribute (tree *node, tree ARG_UNUSED (name), tree args,
448 int ARG_UNUSED (flags),
449 bool * ARG_UNUSED (no_add_attrs))
451 gcc_assert (stdarg_p (*node));
453 if (args)
455 tree position = TREE_VALUE (args);
456 gcc_assert (TREE_CODE (position) == INTEGER_CST);
457 if (tree_int_cst_lt (position, integer_zero_node))
458 gcc_unreachable ();
461 return NULL_TREE;
464 /* Handle a "type_generic" attribute. */
466 static tree
467 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))
471 /* Ensure we have a function type. */
472 gcc_assert (TREE_CODE (*node) == FUNCTION_TYPE);
474 /* Ensure we have a variadic function. */
475 gcc_assert (!prototype_p (*node) || stdarg_p (*node));
477 return NULL_TREE;
480 /* Handle a "transaction_pure" attribute. */
482 static tree
483 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))
488 /* Ensure we have a function type. */
489 gcc_assert (TREE_CODE (*node) == FUNCTION_TYPE);
491 return NULL_TREE;
494 /* Handle a "returns_twice" attribute. */
496 static tree
497 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))
502 gcc_assert (TREE_CODE (*node) == FUNCTION_DECL);
504 DECL_IS_RETURNS_TWICE (*node) = 1;
506 return NULL_TREE;
509 static tree
510 handle_patchable_function_entry_attribute (tree *, tree, tree, int, bool *)
512 /* Nothing to be done here. */
513 return NULL_TREE;
516 /* Ignore the given attribute. Used when this attribute may be usefully
517 overridden by the target, but is not used generically. */
519 static tree
520 ignore_attribute (tree * ARG_UNUSED (node), tree ARG_UNUSED (name),
521 tree ARG_UNUSED (args), int ARG_UNUSED (flags),
522 bool *no_add_attrs)
524 *no_add_attrs = true;
525 return NULL_TREE;
528 /* Handle a "format" attribute; arguments as in
529 struct attribute_spec.handler. */
531 static tree
532 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)
536 *no_add_attrs = true;
537 return NULL_TREE;
541 /* Handle a "format_arg" attribute; arguments as in
542 struct attribute_spec.handler. */
544 tree
545 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)
549 *no_add_attrs = true;
550 return NULL_TREE;
554 /* Handle a "fn spec" attribute; arguments as in
555 struct attribute_spec.handler. */
557 static tree
558 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)
562 gcc_assert (args
563 && TREE_CODE (TREE_VALUE (args)) == STRING_CST
564 && !TREE_CHAIN (args));
565 return NULL_TREE;
568 /* Handle an "visibility" attribute; arguments as in
569 struct attribute_spec.handler. */
571 static tree
572 handle_visibility_attribute (tree *node, tree name, tree args,
573 int ARG_UNUSED (flags),
574 bool *ARG_UNUSED (no_add_attrs))
576 tree decl = *node;
577 tree id = TREE_VALUE (args);
578 enum symbol_visibility vis;
580 if (TYPE_P (*node))
582 if (TREE_CODE (*node) == ENUMERAL_TYPE)
583 /* OK. */;
584 else if (!RECORD_OR_UNION_TYPE_P (*node))
586 warning (OPT_Wattributes, "%qE attribute ignored on non-class types",
587 name);
588 return NULL_TREE;
590 else if (TYPE_FIELDS (*node))
592 error ("%qE attribute ignored because %qT is already defined",
593 name, *node);
594 return NULL_TREE;
597 else if (decl_function_context (decl) != 0 || !TREE_PUBLIC (decl))
599 warning (OPT_Wattributes, "%qE attribute ignored", name);
600 return NULL_TREE;
603 if (TREE_CODE (id) != STRING_CST)
605 error ("visibility argument not a string");
606 return NULL_TREE;
609 /* If this is a type, set the visibility on the type decl. */
610 if (TYPE_P (decl))
612 decl = TYPE_NAME (decl);
613 if (!decl)
614 return NULL_TREE;
615 if (TREE_CODE (decl) == IDENTIFIER_NODE)
617 warning (OPT_Wattributes, "%qE attribute ignored on types",
618 name);
619 return NULL_TREE;
623 if (strcmp (TREE_STRING_POINTER (id), "default") == 0)
624 vis = VISIBILITY_DEFAULT;
625 else if (strcmp (TREE_STRING_POINTER (id), "internal") == 0)
626 vis = VISIBILITY_INTERNAL;
627 else if (strcmp (TREE_STRING_POINTER (id), "hidden") == 0)
628 vis = VISIBILITY_HIDDEN;
629 else if (strcmp (TREE_STRING_POINTER (id), "protected") == 0)
630 vis = VISIBILITY_PROTECTED;
631 else
633 error ("attribute %qE argument must be one of %qs, %qs, %qs, or %qs",
634 name, "default", "hidden", "protected", "internal");
635 vis = VISIBILITY_DEFAULT;
638 if (DECL_VISIBILITY_SPECIFIED (decl)
639 && vis != DECL_VISIBILITY (decl))
641 tree attributes = (TYPE_P (*node)
642 ? TYPE_ATTRIBUTES (*node)
643 : DECL_ATTRIBUTES (decl));
644 if (lookup_attribute ("visibility", attributes))
645 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");
656 DECL_VISIBILITY (decl) = vis;
657 DECL_VISIBILITY_SPECIFIED (decl) = 1;
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. */
664 return NULL_TREE;
667 /* Handle a "always_inline" attribute; arguments as in
668 struct attribute_spec.handler. */
670 static tree
671 handle_always_inline_attribute (tree *node, tree name,
672 tree ARG_UNUSED (args),
673 int ARG_UNUSED (flags),
674 bool *no_add_attrs)
676 if (TREE_CODE (*node) == FUNCTION_DECL)
678 /* Set the attribute and mark it for disregarding inline
679 limits. */
680 DECL_DISREGARD_INLINE_LIMITS (*node) = 1;
682 else
684 warning (OPT_Wattributes, "%qE attribute ignored", name);
685 *no_add_attrs = true;
688 return NULL_TREE;
691 /* Handle a "cold" and attribute; arguments as in
692 struct attribute_spec.handler. */
694 static tree
695 handle_cold_attribute (tree *node, tree name, tree ARG_UNUSED (args),
696 int ARG_UNUSED (flags), bool *no_add_attrs)
698 if (TREE_CODE (*node) == FUNCTION_DECL
699 || TREE_CODE (*node) == LABEL_DECL)
701 /* Attribute cold processing is done later with lookup_attribute. */
703 else
705 warning (OPT_Wattributes, "%qE attribute ignored", name);
706 *no_add_attrs = true;
709 return NULL_TREE;
712 /* Handle a "noinline" attribute; arguments as in
713 struct attribute_spec.handler. */
715 static tree
716 handle_noinline_attribute (tree *node, tree name,
717 tree ARG_UNUSED (args),
718 int ARG_UNUSED (flags), bool *no_add_attrs)
720 if (TREE_CODE (*node) == FUNCTION_DECL)
721 DECL_UNINLINABLE (*node) = 1;
722 else
724 warning (OPT_Wattributes, "%qE attribute ignored", name);
725 *no_add_attrs = true;
728 return NULL_TREE;
731 /* Handle a "weak" attribute; arguments as in
732 struct attribute_spec.handler. */
734 static tree
735 handle_weak_attribute (tree *node, tree name,
736 tree ARG_UNUSED (args),
737 int ARG_UNUSED (flags),
738 bool * ARG_UNUSED (no_add_attrs))
740 if (TREE_CODE (*node) == FUNCTION_DECL
741 && DECL_DECLARED_INLINE_P (*node))
743 warning (OPT_Wattributes, "inline function %q+D declared weak", *node);
744 *no_add_attrs = true;
746 else if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (*node)))
748 error ("indirect function %q+D cannot be declared weak", *node);
749 *no_add_attrs = true;
750 return NULL_TREE;
752 else if (VAR_OR_FUNCTION_DECL_P (*node))
753 declare_weak (*node);
754 else
755 warning (OPT_Wattributes, "%qE attribute ignored", name);
757 return NULL_TREE;
760 /* Handle a "target" attribute. */
762 static tree
763 handle_target_attribute (tree *node, tree name, tree args, int flags,
764 bool *no_add_attrs)
766 /* Ensure we have a function declaration. */
767 if (TREE_CODE (*node) != FUNCTION_DECL)
769 warning (OPT_Wattributes, "%qE attribute ignored", name);
770 *no_add_attrs = true;
772 else if (! targetm.target_option.valid_attribute_p (*node, name, args,
773 flags))
774 *no_add_attrs = true;
776 /* Check that there's no empty string in values of the attribute. */
777 for (tree t = args; t != NULL_TREE; t = TREE_CHAIN (t))
779 tree value = TREE_VALUE (t);
780 if (TREE_CODE (value) == STRING_CST
781 && TREE_STRING_LENGTH (value) == 1
782 && TREE_STRING_POINTER (value)[0] == '\0')
784 warning (OPT_Wattributes, "empty string in attribute %<target%>");
785 *no_add_attrs = true;
789 return NULL_TREE;
792 /* Handle a "used" attribute; arguments as in
793 struct attribute_spec.handler. */
795 static tree
796 handle_used_attribute (tree *pnode, tree name, tree ARG_UNUSED (args),
797 int ARG_UNUSED (flags), bool *no_add_attrs)
799 tree node = *pnode;
801 if (TREE_CODE (node) == FUNCTION_DECL
802 || (VAR_P (node) && TREE_STATIC (node))
803 || (TREE_CODE (node) == TYPE_DECL))
805 TREE_USED (node) = 1;
806 DECL_PRESERVE_P (node) = 1;
807 if (VAR_P (node))
808 DECL_READ_P (node) = 1;
810 else
812 warning (OPT_Wattributes, "%qE attribute ignored", name);
813 *no_add_attrs = true;
816 return NULL_TREE;
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. */
823 static tree
824 handle_alias_ifunc_attribute (bool is_alias, tree *node, tree name, tree args,
825 bool *no_add_attrs)
827 tree decl = *node;
829 if (TREE_CODE (decl) != FUNCTION_DECL
830 && (!is_alias || !VAR_P (decl)))
832 warning (OPT_Wattributes, "%qE attribute ignored", name);
833 *no_add_attrs = true;
835 else if ((TREE_CODE (decl) == FUNCTION_DECL && DECL_INITIAL (decl))
836 || (TREE_CODE (decl) != FUNCTION_DECL
837 && 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 || (TREE_CODE (decl) != FUNCTION_DECL
841 && ! TREE_PUBLIC (decl) && DECL_INITIAL (decl)))
843 error ("%q+D defined both normally and as %qE attribute", decl, name);
844 *no_add_attrs = true;
845 return NULL_TREE;
847 else if (!is_alias
848 && (lookup_attribute ("weak", DECL_ATTRIBUTES (decl))
849 || lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))))
851 error ("weak %q+D cannot be defined %qE", decl, name);
852 *no_add_attrs = true;
853 return NULL_TREE;
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 else if (decl_function_context (decl) == 0 && current_function_decl == NULL)
863 tree id;
865 id = TREE_VALUE (args);
866 if (TREE_CODE (id) != STRING_CST)
868 error ("attribute %qE argument not a string", name);
869 *no_add_attrs = true;
870 return NULL_TREE;
872 id = get_identifier (TREE_STRING_POINTER (id));
873 /* This counts as a use of the object pointed to. */
874 TREE_USED (id) = 1;
876 if (TREE_CODE (decl) == FUNCTION_DECL)
877 DECL_INITIAL (decl) = error_mark_node;
878 else
879 TREE_STATIC (decl) = 1;
881 if (!is_alias)
883 /* ifuncs are also aliases, so set that attribute too. */
884 DECL_ATTRIBUTES (decl)
885 = tree_cons (get_identifier ("alias"), args,
886 DECL_ATTRIBUTES (decl));
887 DECL_ATTRIBUTES (decl) = tree_cons (get_identifier ("ifunc"),
888 NULL, DECL_ATTRIBUTES (decl));
891 else
893 warning (OPT_Wattributes, "%qE attribute ignored", name);
894 *no_add_attrs = true;
897 if (decl_in_symtab_p (*node))
899 struct symtab_node *n = symtab_node::get (decl);
900 if (n && n->refuse_visibility_changes)
901 error ("%+qD declared %qs after being used",
902 decl, is_alias ? "alias" : "ifunc");
906 return NULL_TREE;
909 /* Handle an "alias" or "ifunc" attribute; arguments as in
910 struct attribute_spec.handler. */
912 static tree
913 handle_alias_attribute (tree *node, tree name, tree args,
914 int ARG_UNUSED (flags), bool *no_add_attrs)
916 return handle_alias_ifunc_attribute (true, node, name, args, no_add_attrs);
919 /* (end of attribute-handling). */
921 /* Language-dependent contents of a type. */
923 struct GTY(()) lang_type
925 char dummy;
928 /* Language-dependent contents of a decl. */
930 struct GTY((variable_size)) lang_decl
932 char dummy;
935 /* Language-dependent contents of an identifier. This must include a
936 tree_identifier. */
938 struct GTY(()) lang_identifier
940 struct tree_identifier common;
943 /* The resulting tree type. */
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
949 union tree_node GTY((tag ("0"),
950 desc ("tree_node_structure (&%h)"))) generic;
951 struct lang_identifier GTY((tag ("1"))) identifier;
954 /* We don't use language_function. */
956 struct GTY(()) language_function
958 int dummy;
961 /* GC-marking callback for use from jit_root_tab.
963 If there's an active playback context, call its marking method
964 so that it can mark any pointers it references. */
966 static void my_ggc_walker (void *)
968 if (gcc::jit::active_playback_ctxt)
969 gcc::jit::active_playback_ctxt->gt_ggc_mx ();
972 const char *dummy;
974 struct ggc_root_tab jit_root_tab[] =
977 &dummy, 1, 0, my_ggc_walker, NULL
979 LAST_GGC_ROOT_TAB
982 /* JIT-specific implementation of diagnostic callbacks. */
984 /* Implementation of "begin_diagnostic". */
986 static void
987 jit_begin_diagnostic (diagnostic_context */*context*/,
988 const diagnostic_info */*diagnostic*/)
990 gcc_assert (gcc::jit::active_playback_ctxt);
991 JIT_LOG_SCOPE (gcc::jit::active_playback_ctxt->get_logger ());
993 /* No-op (apart from logging); the real error-handling is done in the
994 "end_diagnostic" hook. */
997 /* Implementation of "end_diagnostic". */
999 static void
1000 jit_end_diagnostic (diagnostic_context *context,
1001 const diagnostic_info *diagnostic,
1002 diagnostic_t)
1004 gcc_assert (gcc::jit::active_playback_ctxt);
1005 JIT_LOG_SCOPE (gcc::jit::active_playback_ctxt->get_logger ());
1007 /* Delegate to the playback context (and thence to the
1008 recording context). */
1009 gcc_assert (diagnostic);
1010 gcc::jit::active_playback_ctxt->add_diagnostic (context, *diagnostic);
1013 /* Language hooks. */
1015 static bool
1016 jit_langhook_init (void)
1018 gcc_assert (gcc::jit::active_playback_ctxt);
1019 JIT_LOG_SCOPE (gcc::jit::active_playback_ctxt->get_logger ());
1021 static bool registered_root_tab = false;
1022 if (!registered_root_tab)
1024 ggc_register_root_tab (jit_root_tab);
1025 registered_root_tab = true;
1028 gcc_assert (global_dc);
1029 diagnostic_starter (global_dc) = jit_begin_diagnostic;
1030 diagnostic_finalizer (global_dc) = jit_end_diagnostic;
1032 build_common_tree_nodes (false);
1034 build_common_builtin_nodes ();
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 mpfr_set_default_prec (256);
1041 return true;
1044 static void
1045 jit_langhook_parse_file (void)
1047 /* Replay the activity by the client, recorded on the context. */
1048 gcc_assert (gcc::jit::active_playback_ctxt);
1049 gcc::jit::active_playback_ctxt->replay ();
1052 static tree
1053 jit_langhook_type_for_mode (machine_mode mode, int unsignedp)
1055 /* Build any vector types here (see PR 46805). */
1056 if (VECTOR_MODE_P (mode))
1058 tree inner;
1060 inner = jit_langhook_type_for_mode (GET_MODE_INNER (mode), unsignedp);
1061 if (inner != NULL_TREE)
1062 return build_vector_type_for_mode (inner, mode);
1063 return NULL_TREE;
1066 if (mode == TYPE_MODE (float_type_node))
1067 return float_type_node;
1069 if (mode == TYPE_MODE (double_type_node))
1070 return double_type_node;
1072 if (mode == TYPE_MODE (intQI_type_node))
1073 return unsignedp ? unsigned_intQI_type_node : intQI_type_node;
1074 if (mode == TYPE_MODE (intHI_type_node))
1075 return unsignedp ? unsigned_intHI_type_node : intHI_type_node;
1076 if (mode == TYPE_MODE (intSI_type_node))
1077 return unsignedp ? unsigned_intSI_type_node : intSI_type_node;
1078 if (mode == TYPE_MODE (intDI_type_node))
1079 return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
1080 if (mode == TYPE_MODE (intTI_type_node))
1081 return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
1083 if (mode == TYPE_MODE (integer_type_node))
1084 return unsignedp ? unsigned_type_node : integer_type_node;
1086 if (mode == TYPE_MODE (long_integer_type_node))
1087 return unsignedp ? long_unsigned_type_node : long_integer_type_node;
1089 if (mode == TYPE_MODE (long_long_integer_type_node))
1090 return unsignedp ? long_long_unsigned_type_node : long_long_integer_type_node;
1092 if (COMPLEX_MODE_P (mode))
1094 if (mode == TYPE_MODE (complex_float_type_node))
1095 return complex_float_type_node;
1096 if (mode == TYPE_MODE (complex_double_type_node))
1097 return complex_double_type_node;
1098 if (mode == TYPE_MODE (complex_long_double_type_node))
1099 return complex_long_double_type_node;
1100 if (mode == TYPE_MODE (complex_integer_type_node) && !unsignedp)
1101 return complex_integer_type_node;
1104 /* gcc_unreachable */
1105 return NULL;
1108 /* Record a builtin function. We just ignore builtin functions. */
1110 static tree
1111 jit_langhook_builtin_function (tree decl)
1113 return decl;
1116 static bool
1117 jit_langhook_global_bindings_p (void)
1119 return true;
1122 static tree
1123 jit_langhook_pushdecl (tree decl ATTRIBUTE_UNUSED)
1125 gcc_unreachable ();
1128 static tree
1129 jit_langhook_getdecls (void)
1131 return NULL;
1134 #undef LANG_HOOKS_NAME
1135 #define LANG_HOOKS_NAME "libgccjit"
1137 #undef LANG_HOOKS_INIT
1138 #define LANG_HOOKS_INIT jit_langhook_init
1140 #undef LANG_HOOKS_PARSE_FILE
1141 #define LANG_HOOKS_PARSE_FILE jit_langhook_parse_file
1143 #undef LANG_HOOKS_TYPE_FOR_MODE
1144 #define LANG_HOOKS_TYPE_FOR_MODE jit_langhook_type_for_mode
1146 #undef LANG_HOOKS_BUILTIN_FUNCTION
1147 #define LANG_HOOKS_BUILTIN_FUNCTION jit_langhook_builtin_function
1149 #undef LANG_HOOKS_GLOBAL_BINDINGS_P
1150 #define LANG_HOOKS_GLOBAL_BINDINGS_P jit_langhook_global_bindings_p
1152 #undef LANG_HOOKS_PUSHDECL
1153 #define LANG_HOOKS_PUSHDECL jit_langhook_pushdecl
1155 #undef LANG_HOOKS_GETDECLS
1156 #define LANG_HOOKS_GETDECLS jit_langhook_getdecls
1158 /* Attribute hooks. */
1159 #undef LANG_HOOKS_ATTRIBUTE_TABLE
1160 #define LANG_HOOKS_ATTRIBUTE_TABLE jit_attribute_table
1162 #undef LANG_HOOKS_DEEP_UNSHARING
1163 #define LANG_HOOKS_DEEP_UNSHARING true
1165 struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
1167 #include "gt-jit-dummy-frontend.h"
1168 #include "gtype-jit.h"