1/* jit.c -- Dummy "frontend" for use during JIT-compilation.
2   Copyright (C) 2013-2022 Free Software Foundation, Inc.
3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free
8Software Foundation; either version 3, or (at your option) any later
9version.
10
11GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14for more details.
15
16You should have received a copy of the GNU General Public License
17along 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
33#include <mpfr.h>
34
35/* Attribute handling.  */
36
37static tree handle_noreturn_attribute (tree *, tree, tree, int, bool *);
38static tree handle_leaf_attribute (tree *, tree, tree, int, bool *);
39static tree handle_const_attribute (tree *, tree, tree, int, bool *);
40static tree handle_malloc_attribute (tree *, tree, tree, int, bool *);
41static tree handle_pure_attribute (tree *, tree, tree, int, bool *);
42static tree handle_novops_attribute (tree *, tree, tree, int, bool *);
43static tree handle_nonnull_attribute (tree *, tree, tree, int, bool *);
44static tree handle_nothrow_attribute (tree *, tree, tree, int, bool *);
45static tree handle_sentinel_attribute (tree *, tree, tree, int, bool *);
46static tree handle_type_generic_attribute (tree *, tree, tree, int, bool *);
47static tree handle_transaction_pure_attribute (tree *, tree, tree, int, bool *);
48static tree handle_returns_twice_attribute (tree *, tree, tree, int, bool *);
49static tree handle_patchable_function_entry_attribute (tree *, tree, tree,
50						       int, bool *);
51static tree ignore_attribute (tree *, tree, tree, int, bool *);
52
53static tree handle_format_attribute (tree *, tree, tree, int, bool *);
54static tree handle_fnspec_attribute (tree *, tree, tree, int, bool *);
55static tree handle_format_arg_attribute (tree *, tree, tree, int, bool *);
56
57/* Helper to define attribute exclusions.  */
58#define ATTR_EXCL(name, function, type, variable)	\
59  { name, function, type, variable }
60
61/* Define attributes that are mutually exclusive with one another.  */
62static const struct attribute_spec::exclusions attr_noreturn_exclusions[] =
63{
64  ATTR_EXCL ("noreturn", true, true, true),
65  ATTR_EXCL ("alloc_align", true, true, true),
66  ATTR_EXCL ("alloc_size", true, true, true),
67  ATTR_EXCL ("const", true, true, true),
68  ATTR_EXCL ("malloc", true, true, true),
69  ATTR_EXCL ("pure", true, true, true),
70  ATTR_EXCL ("returns_twice", true, true, true),
71  ATTR_EXCL ("warn_unused_result", true, true, true),
72  ATTR_EXCL (NULL, false, false, false),
73};
74
75static const struct attribute_spec::exclusions attr_returns_twice_exclusions[] =
76{
77  ATTR_EXCL ("noreturn", true, true, true),
78  ATTR_EXCL (NULL, false, false, false),
79};
80
81static const struct attribute_spec::exclusions attr_const_pure_exclusions[] =
82{
83  ATTR_EXCL ("const", true, true, true),
84  ATTR_EXCL ("noreturn", true, true, true),
85  ATTR_EXCL ("pure", true, true, true),
86  ATTR_EXCL (NULL, false, false, false)
87};
88
89/* Table of machine-independent attributes supported in libgccjit.  */
90const struct attribute_spec jit_attribute_table[] =
91{
92  /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
93       affects_type_identity, handler, exclude } */
94  { "noreturn",               0, 0, true,  false, false, false,
95			      handle_noreturn_attribute,
96			      attr_noreturn_exclusions },
97  { "leaf",		      0, 0, true,  false, false, false,
98			      handle_leaf_attribute, NULL },
99  /* The same comments as for noreturn attributes apply to const ones.  */
100  { "const",                  0, 0, true,  false, false, false,
101			      handle_const_attribute,
102			      attr_const_pure_exclusions },
103  { "malloc",                 0, 0, true,  false, false, false,
104			      handle_malloc_attribute, NULL },
105  { "pure",                   0, 0, true,  false, false, false,
106			      handle_pure_attribute,
107			      attr_const_pure_exclusions },
108  { "no vops",                0, 0, true,  false, false, false,
109			      handle_novops_attribute, NULL },
110  { "nonnull",                0, -1, false, true, true, false,
111			      handle_nonnull_attribute, NULL },
112  { "nothrow",                0, 0, true,  false, false, false,
113			      handle_nothrow_attribute, NULL },
114  { "patchable_function_entry", 1, 2, true, false, false, false,
115			      handle_patchable_function_entry_attribute,
116			      NULL },
117  { "returns_twice",          0, 0, true,  false, false, false,
118			      handle_returns_twice_attribute,
119			      attr_returns_twice_exclusions },
120  { "sentinel",               0, 1, false, true, true, false,
121			      handle_sentinel_attribute, NULL },
122  { "type generic",           0, 0, false, true, true, false,
123			      handle_type_generic_attribute, NULL },
124  { "fn spec",	 	      1, 1, false, true, true, false,
125			      handle_fnspec_attribute, NULL },
126  { "transaction_pure",	      0, 0, false, true, true, false,
127			      handle_transaction_pure_attribute, NULL },
128  /* For internal use only.  The leading '*' both prevents its usage in
129     source code and signals that it may be overridden by machine tables.  */
130  { "*tm regparm",            0, 0, false, true, true, false,
131			      ignore_attribute, NULL },
132  { NULL,                     0, 0, false, false, false, false, NULL, NULL }
133};
134
135/* Give the specifications for the format attributes, used by C and all
136   descendants.  */
137
138const struct attribute_spec jit_format_attribute_table[] =
139{
140  /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
141       affects_type_identity, handler, exclude } */
142  { "format",                 3, 3, false, true,  true, false,
143			      handle_format_attribute, NULL },
144  { "format_arg",             1, 1, false, true,  true, false,
145			      handle_format_arg_attribute, NULL },
146  { NULL,                     0, 0, false, false, false, false, NULL, NULL }
147};
148
149/* Attribute handlers.  */
150
151/* Handle a "noreturn" attribute; arguments as in
152   struct attribute_spec.handler.  */
153
154static tree
155handle_noreturn_attribute (tree *node, tree ARG_UNUSED (name),
156			   tree ARG_UNUSED (args), int ARG_UNUSED (flags),
157			   bool * ARG_UNUSED (no_add_attrs))
158{
159  tree type = TREE_TYPE (*node);
160
161  if (TREE_CODE (*node) == FUNCTION_DECL)
162    TREE_THIS_VOLATILE (*node) = 1;
163  else if (TREE_CODE (type) == POINTER_TYPE
164	   && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
165    TREE_TYPE (*node)
166      = build_pointer_type
167	(build_type_variant (TREE_TYPE (type),
168			     TYPE_READONLY (TREE_TYPE (type)), 1));
169  else
170    gcc_unreachable ();
171
172  return NULL_TREE;
173}
174
175/* Handle a "leaf" attribute; arguments as in
176   struct attribute_spec.handler.  */
177
178static tree
179handle_leaf_attribute (tree *node, tree name,
180		       tree ARG_UNUSED (args),
181		       int ARG_UNUSED (flags), bool *no_add_attrs)
182{
183  if (TREE_CODE (*node) != FUNCTION_DECL)
184    {
185      warning (OPT_Wattributes, "%qE attribute ignored", name);
186      *no_add_attrs = true;
187    }
188  if (!TREE_PUBLIC (*node))
189    {
190      warning (OPT_Wattributes, "%qE attribute has no effect on unit local functions", name);
191      *no_add_attrs = true;
192    }
193
194  return NULL_TREE;
195}
196
197/* Handle a "const" attribute; arguments as in
198   struct attribute_spec.handler.  */
199
200static tree
201handle_const_attribute (tree *node, tree ARG_UNUSED (name),
202			tree ARG_UNUSED (args), int ARG_UNUSED (flags),
203			bool * ARG_UNUSED (no_add_attrs))
204{
205  if (TREE_CODE (*node) != FUNCTION_DECL
206      || !fndecl_built_in_p (*node))
207    inform (UNKNOWN_LOCATION, "%s:%s: %E: %E", __FILE__, __func__, *node, name);
208
209  tree type = TREE_TYPE (*node);
210
211  /* See FIXME comment on noreturn in c_common_attribute_table.  */
212  if (TREE_CODE (*node) == FUNCTION_DECL)
213    TREE_READONLY (*node) = 1;
214  else if (TREE_CODE (type) == POINTER_TYPE
215	   && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
216    TREE_TYPE (*node)
217      = build_pointer_type
218	(build_type_variant (TREE_TYPE (type), 1,
219			     TREE_THIS_VOLATILE (TREE_TYPE (type))));
220  else
221    gcc_unreachable ();
222
223  return NULL_TREE;
224}
225
226
227/* Handle a "malloc" attribute; arguments as in
228   struct attribute_spec.handler.  */
229
230static tree
231handle_malloc_attribute (tree *node, tree ARG_UNUSED (name),
232			 tree ARG_UNUSED (args), int ARG_UNUSED (flags),
233			 bool * ARG_UNUSED (no_add_attrs))
234{
235  if (TREE_CODE (*node) == FUNCTION_DECL
236      && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (*node))))
237    DECL_IS_MALLOC (*node) = 1;
238  else
239    gcc_unreachable ();
240
241  return NULL_TREE;
242}
243
244
245/* Handle a "pure" attribute; arguments as in
246   struct attribute_spec.handler.  */
247
248static tree
249handle_pure_attribute (tree *node, tree ARG_UNUSED (name),
250		       tree ARG_UNUSED (args), int ARG_UNUSED (flags),
251		       bool * ARG_UNUSED (no_add_attrs))
252{
253  if (TREE_CODE (*node) == FUNCTION_DECL)
254    DECL_PURE_P (*node) = 1;
255  else
256    gcc_unreachable ();
257
258  return NULL_TREE;
259}
260
261
262/* Handle a "no vops" attribute; arguments as in
263   struct attribute_spec.handler.  */
264
265static tree
266handle_novops_attribute (tree *node, tree ARG_UNUSED (name),
267			 tree ARG_UNUSED (args), int ARG_UNUSED (flags),
268			 bool *ARG_UNUSED (no_add_attrs))
269{
270  gcc_assert (TREE_CODE (*node) == FUNCTION_DECL);
271  DECL_IS_NOVOPS (*node) = 1;
272  return NULL_TREE;
273}
274
275
276/* Helper for nonnull attribute handling; fetch the operand number
277   from the attribute argument list.  */
278
279static bool
280get_nonnull_operand (tree arg_num_expr, unsigned HOST_WIDE_INT *valp)
281{
282  /* Verify the arg number is a constant.  */
283  if (!tree_fits_uhwi_p (arg_num_expr))
284    return false;
285
286  *valp = TREE_INT_CST_LOW (arg_num_expr);
287  return true;
288}
289
290/* Handle the "nonnull" attribute.  */
291
292static tree
293handle_nonnull_attribute (tree *node, tree ARG_UNUSED (name),
294			  tree args, int ARG_UNUSED (flags),
295			  bool * ARG_UNUSED (no_add_attrs))
296{
297  tree type = *node;
298
299  /* If no arguments are specified, all pointer arguments should be
300     non-null.  Verify a full prototype is given so that the arguments
301     will have the correct types when we actually check them later.
302     Avoid diagnosing type-generic built-ins since those have no
303     prototype.  */
304  if (!args)
305    {
306      gcc_assert (prototype_p (type)
307		  || !TYPE_ATTRIBUTES (type)
308		  || lookup_attribute ("type generic", TYPE_ATTRIBUTES (type)));
309
310      return NULL_TREE;
311    }
312
313  /* Argument list specified.  Verify that each argument number references
314     a pointer argument.  */
315  for (; args; args = TREE_CHAIN (args))
316    {
317      tree argument;
318      unsigned HOST_WIDE_INT arg_num = 0, ck_num;
319
320      if (!get_nonnull_operand (TREE_VALUE (args), &arg_num))
321	gcc_unreachable ();
322
323      argument = TYPE_ARG_TYPES (type);
324      if (argument)
325	{
326	  for (ck_num = 1; ; ck_num++)
327	    {
328	      if (!argument || ck_num == arg_num)
329		break;
330	      argument = TREE_CHAIN (argument);
331	    }
332
333	  gcc_assert (argument
334		      && TREE_CODE (TREE_VALUE (argument)) == POINTER_TYPE);
335	}
336    }
337
338  return NULL_TREE;
339}
340
341
342/* Handle a "nothrow" attribute; arguments as in
343   struct attribute_spec.handler.  */
344
345static tree
346handle_nothrow_attribute (tree *node, tree ARG_UNUSED (name),
347			  tree ARG_UNUSED (args), int ARG_UNUSED (flags),
348			  bool * ARG_UNUSED (no_add_attrs))
349{
350  if (TREE_CODE (*node) == FUNCTION_DECL)
351    TREE_NOTHROW (*node) = 1;
352  else
353    gcc_unreachable ();
354
355  return NULL_TREE;
356}
357
358
359/* Handle a "sentinel" attribute.  */
360
361static tree
362handle_sentinel_attribute (tree *node, tree ARG_UNUSED (name), tree args,
363			   int ARG_UNUSED (flags),
364			   bool * ARG_UNUSED (no_add_attrs))
365{
366  gcc_assert (stdarg_p (*node));
367
368  if (args)
369    {
370      tree position = TREE_VALUE (args);
371      gcc_assert (TREE_CODE (position) == INTEGER_CST);
372      if (tree_int_cst_lt (position, integer_zero_node))
373	gcc_unreachable ();
374    }
375
376  return NULL_TREE;
377}
378
379/* Handle a "type_generic" attribute.  */
380
381static tree
382handle_type_generic_attribute (tree *node, tree ARG_UNUSED (name),
383			       tree ARG_UNUSED (args), int ARG_UNUSED (flags),
384			       bool * ARG_UNUSED (no_add_attrs))
385{
386  /* Ensure we have a function type.  */
387  gcc_assert (TREE_CODE (*node) == FUNCTION_TYPE);
388
389  /* Ensure we have a variadic function.  */
390  gcc_assert (!prototype_p (*node) || stdarg_p (*node));
391
392  return NULL_TREE;
393}
394
395/* Handle a "transaction_pure" attribute.  */
396
397static tree
398handle_transaction_pure_attribute (tree *node, tree ARG_UNUSED (name),
399				   tree ARG_UNUSED (args),
400				   int ARG_UNUSED (flags),
401				   bool * ARG_UNUSED (no_add_attrs))
402{
403  /* Ensure we have a function type.  */
404  gcc_assert (TREE_CODE (*node) == FUNCTION_TYPE);
405
406  return NULL_TREE;
407}
408
409/* Handle a "returns_twice" attribute.  */
410
411static tree
412handle_returns_twice_attribute (tree *node, tree ARG_UNUSED (name),
413				tree ARG_UNUSED (args),
414				int ARG_UNUSED (flags),
415				bool * ARG_UNUSED (no_add_attrs))
416{
417  gcc_assert (TREE_CODE (*node) == FUNCTION_DECL);
418
419  DECL_IS_RETURNS_TWICE (*node) = 1;
420
421  return NULL_TREE;
422}
423
424static tree
425handle_patchable_function_entry_attribute (tree *, tree, tree, int, bool *)
426{
427  /* Nothing to be done here.  */
428  return NULL_TREE;
429}
430
431/* Ignore the given attribute.  Used when this attribute may be usefully
432   overridden by the target, but is not used generically.  */
433
434static tree
435ignore_attribute (tree * ARG_UNUSED (node), tree ARG_UNUSED (name),
436		  tree ARG_UNUSED (args), int ARG_UNUSED (flags),
437		  bool *no_add_attrs)
438{
439  *no_add_attrs = true;
440  return NULL_TREE;
441}
442
443/* Handle a "format" attribute; arguments as in
444   struct attribute_spec.handler.  */
445
446static tree
447handle_format_attribute (tree * ARG_UNUSED (node), tree ARG_UNUSED (name),
448			 tree ARG_UNUSED (args), int ARG_UNUSED (flags),
449			 bool *no_add_attrs)
450{
451  *no_add_attrs = true;
452  return NULL_TREE;
453}
454
455
456/* Handle a "format_arg" attribute; arguments as in
457   struct attribute_spec.handler.  */
458
459tree
460handle_format_arg_attribute (tree * ARG_UNUSED (node), tree ARG_UNUSED (name),
461			     tree ARG_UNUSED (args), int ARG_UNUSED (flags),
462			     bool *no_add_attrs)
463{
464  *no_add_attrs = true;
465  return NULL_TREE;
466}
467
468
469/* Handle a "fn spec" attribute; arguments as in
470   struct attribute_spec.handler.  */
471
472static tree
473handle_fnspec_attribute (tree *node ATTRIBUTE_UNUSED, tree ARG_UNUSED (name),
474			 tree args, int ARG_UNUSED (flags),
475			 bool *no_add_attrs ATTRIBUTE_UNUSED)
476{
477  gcc_assert (args
478	      && TREE_CODE (TREE_VALUE (args)) == STRING_CST
479	      && !TREE_CHAIN (args));
480  return NULL_TREE;
481}
482
483/* (end of attribute-handling).  */
484
485/* Language-dependent contents of a type.  */
486
487struct GTY(()) lang_type
488{
489  char dummy;
490};
491
492/* Language-dependent contents of a decl.  */
493
494struct GTY((variable_size)) lang_decl
495{
496  char dummy;
497};
498
499/* Language-dependent contents of an identifier.  This must include a
500   tree_identifier.  */
501
502struct GTY(()) lang_identifier
503{
504  struct tree_identifier common;
505};
506
507/* The resulting tree type.  */
508
509union GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"),
510	   chain_next ("CODE_CONTAINS_STRUCT (TREE_CODE (&%h.generic), TS_COMMON) ? ((union lang_tree_node *) TREE_CHAIN (&%h.generic)) : NULL")))
511lang_tree_node
512{
513  union tree_node GTY((tag ("0"),
514		       desc ("tree_node_structure (&%h)"))) generic;
515  struct lang_identifier GTY((tag ("1"))) identifier;
516};
517
518/* We don't use language_function.  */
519
520struct GTY(()) language_function
521{
522  int dummy;
523};
524
525/* GC-marking callback for use from jit_root_tab.
526
527   If there's an active playback context, call its marking method
528   so that it can mark any pointers it references.  */
529
530static void my_ggc_walker (void *)
531{
532  if (gcc::jit::active_playback_ctxt)
533    gcc::jit::active_playback_ctxt->gt_ggc_mx ();
534}
535
536const char *dummy;
537
538struct ggc_root_tab jit_root_tab[] =
539  {
540    {
541      &dummy, 1, 0, my_ggc_walker, NULL
542    },
543    LAST_GGC_ROOT_TAB
544  };
545
546/* JIT-specific implementation of diagnostic callbacks.  */
547
548/* Implementation of "begin_diagnostic".  */
549
550static void
551jit_begin_diagnostic (diagnostic_context */*context*/,
552		      diagnostic_info */*diagnostic*/)
553{
554  gcc_assert (gcc::jit::active_playback_ctxt);
555  JIT_LOG_SCOPE (gcc::jit::active_playback_ctxt->get_logger ());
556
557  /* No-op (apart from logging); the real error-handling is done in the
558     "end_diagnostic" hook.  */
559}
560
561/* Implementation of "end_diagnostic".  */
562
563static void
564jit_end_diagnostic (diagnostic_context *context,
565		    diagnostic_info *diagnostic,
566		    diagnostic_t)
567{
568  gcc_assert (gcc::jit::active_playback_ctxt);
569  JIT_LOG_SCOPE (gcc::jit::active_playback_ctxt->get_logger ());
570
571  /* Delegate to the playback context (and thence to the
572     recording context).  */
573  gcc::jit::active_playback_ctxt->add_diagnostic (context, diagnostic);
574}
575
576/* Language hooks.  */
577
578static bool
579jit_langhook_init (void)
580{
581  gcc_assert (gcc::jit::active_playback_ctxt);
582  JIT_LOG_SCOPE (gcc::jit::active_playback_ctxt->get_logger ());
583
584  static bool registered_root_tab = false;
585  if (!registered_root_tab)
586    {
587      ggc_register_root_tab (jit_root_tab);
588      registered_root_tab = true;
589    }
590
591  gcc_assert (global_dc);
592  global_dc->begin_diagnostic = jit_begin_diagnostic;
593  global_dc->end_diagnostic = jit_end_diagnostic;
594
595  build_common_tree_nodes (false);
596
597  /* I don't know why this has to be done explicitly.  */
598  void_list_node = build_tree_list (NULL_TREE, void_type_node);
599
600  build_common_builtin_nodes ();
601
602  /* The default precision for floating point numbers.  This is used
603     for floating point constants with abstract type.  This may
604     eventually be controllable by a command line option.  */
605  mpfr_set_default_prec (256);
606
607  return true;
608}
609
610static void
611jit_langhook_parse_file (void)
612{
613  /* Replay the activity by the client, recorded on the context.  */
614  gcc_assert (gcc::jit::active_playback_ctxt);
615  gcc::jit::active_playback_ctxt->replay ();
616}
617
618static tree
619jit_langhook_type_for_mode (machine_mode mode, int unsignedp)
620{
621  /* Build any vector types here (see PR 46805).  */
622  if (VECTOR_MODE_P (mode))
623    {
624      tree inner;
625
626      inner = jit_langhook_type_for_mode (GET_MODE_INNER (mode), unsignedp);
627      if (inner != NULL_TREE)
628	return build_vector_type_for_mode (inner, mode);
629      return NULL_TREE;
630    }
631
632  if (mode == TYPE_MODE (float_type_node))
633    return float_type_node;
634
635  if (mode == TYPE_MODE (double_type_node))
636    return double_type_node;
637
638  if (mode == TYPE_MODE (intQI_type_node))
639    return unsignedp ? unsigned_intQI_type_node : intQI_type_node;
640  if (mode == TYPE_MODE (intHI_type_node))
641    return unsignedp ? unsigned_intHI_type_node : intHI_type_node;
642  if (mode == TYPE_MODE (intSI_type_node))
643    return unsignedp ? unsigned_intSI_type_node : intSI_type_node;
644  if (mode == TYPE_MODE (intDI_type_node))
645    return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
646  if (mode == TYPE_MODE (intTI_type_node))
647    return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
648
649  if (mode == TYPE_MODE (integer_type_node))
650    return unsignedp ? unsigned_type_node : integer_type_node;
651
652  if (mode == TYPE_MODE (long_integer_type_node))
653    return unsignedp ? long_unsigned_type_node : long_integer_type_node;
654
655  if (mode == TYPE_MODE (long_long_integer_type_node))
656    return unsignedp ? long_long_unsigned_type_node : long_long_integer_type_node;
657
658  if (COMPLEX_MODE_P (mode))
659    {
660      if (mode == TYPE_MODE (complex_float_type_node))
661	return complex_float_type_node;
662      if (mode == TYPE_MODE (complex_double_type_node))
663	return complex_double_type_node;
664      if (mode == TYPE_MODE (complex_long_double_type_node))
665	return complex_long_double_type_node;
666      if (mode == TYPE_MODE (complex_integer_type_node) && !unsignedp)
667	return complex_integer_type_node;
668    }
669
670  /* gcc_unreachable */
671  return NULL;
672}
673
674/* Record a builtin function.  We just ignore builtin functions.  */
675
676static tree
677jit_langhook_builtin_function (tree decl)
678{
679  return decl;
680}
681
682static bool
683jit_langhook_global_bindings_p (void)
684{
685  return true;
686}
687
688static tree
689jit_langhook_pushdecl (tree decl ATTRIBUTE_UNUSED)
690{
691  gcc_unreachable ();
692}
693
694static tree
695jit_langhook_getdecls (void)
696{
697  return NULL;
698}
699
700#undef LANG_HOOKS_NAME
701#define LANG_HOOKS_NAME		"libgccjit"
702
703#undef LANG_HOOKS_INIT
704#define LANG_HOOKS_INIT		jit_langhook_init
705
706#undef LANG_HOOKS_PARSE_FILE
707#define LANG_HOOKS_PARSE_FILE		jit_langhook_parse_file
708
709#undef LANG_HOOKS_TYPE_FOR_MODE
710#define LANG_HOOKS_TYPE_FOR_MODE	jit_langhook_type_for_mode
711
712#undef LANG_HOOKS_BUILTIN_FUNCTION
713#define LANG_HOOKS_BUILTIN_FUNCTION	jit_langhook_builtin_function
714
715#undef LANG_HOOKS_GLOBAL_BINDINGS_P
716#define LANG_HOOKS_GLOBAL_BINDINGS_P	jit_langhook_global_bindings_p
717
718#undef LANG_HOOKS_PUSHDECL
719#define LANG_HOOKS_PUSHDECL		jit_langhook_pushdecl
720
721#undef LANG_HOOKS_GETDECLS
722#define LANG_HOOKS_GETDECLS		jit_langhook_getdecls
723
724/* Attribute hooks.  */
725#undef LANG_HOOKS_COMMON_ATTRIBUTE_TABLE
726#define LANG_HOOKS_COMMON_ATTRIBUTE_TABLE jit_attribute_table
727#undef LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE
728#define LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE jit_format_attribute_table
729
730#undef  LANG_HOOKS_DEEP_UNSHARING
731#define LANG_HOOKS_DEEP_UNSHARING	true
732
733struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
734
735#include "gt-jit-dummy-frontend.h"
736#include "gtype-jit.h"
737