xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/jit/libgccjit.c (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
1 /* Implementation of the C API; all wrappers into the internal C++ API
2    Copyright (C) 2013-2020 Free Software Foundation, Inc.
3    Contributed by David Malcolm <dmalcolm@redhat.com>.
4 
5 This file is part of GCC.
6 
7 GCC is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
11 
12 GCC is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3.  If not see
19 <http://www.gnu.org/licenses/>.  */
20 
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "timevar.h"
25 #include "typed-splay-tree.h"
26 #include "cppbuiltin.h"
27 #include <pthread.h>
28 
29 #include "libgccjit.h"
30 #include "jit-recording.h"
31 #include "jit-result.h"
32 
33 /* The opaque types used by the public API are actually subclasses
34    of the gcc::jit::recording classes.  */
35 
36 struct gcc_jit_context : public gcc::jit::recording::context
37 {
gcc_jit_contextgcc_jit_context38   gcc_jit_context (gcc_jit_context *parent_ctxt) :
39     context (parent_ctxt)
40   {}
41 };
42 
43 struct gcc_jit_result : public gcc::jit::result
44 {
45 };
46 
47 struct gcc_jit_object : public gcc::jit::recording::memento
48 {
49 };
50 
51 struct gcc_jit_location : public gcc::jit::recording::location
52 {
53 };
54 
55 struct gcc_jit_type : public gcc::jit::recording::type
56 {
57 };
58 
59 struct gcc_jit_struct : public gcc::jit::recording::struct_
60 {
61 };
62 
63 struct gcc_jit_field : public gcc::jit::recording::field
64 {
65 };
66 
67 struct gcc_jit_bitfield : public gcc::jit::recording::bitfield
68 {
69 };
70 
71 struct gcc_jit_function : public gcc::jit::recording::function
72 {
73 };
74 
75 struct gcc_jit_block : public gcc::jit::recording::block
76 {
77 };
78 
79 struct gcc_jit_rvalue : public gcc::jit::recording::rvalue
80 {
81 };
82 
83 struct gcc_jit_lvalue : public gcc::jit::recording::lvalue
84 {
85 };
86 
87 struct gcc_jit_param : public gcc::jit::recording::param
88 {
89 };
90 
91 struct gcc_jit_case : public gcc::jit::recording::case_
92 {
93 };
94 
95 struct gcc_jit_timer : public timer
96 {
97 };
98 
99 /**********************************************************************
100  Error-handling.
101 
102  We try to gracefully handle API usage errors by being defensive
103  at the API boundary.
104  **********************************************************************/
105 
106 #define JIT_BEGIN_STMT do {
107 #define JIT_END_STMT   } while(0)
108 
109 /* Each of these error-handling macros determines if TEST_EXPR holds.
110 
111    If TEXT_EXPR fails to hold we return from the enclosing function and
112    print an error, either via adding an error on the given context CTXT
113    if CTXT is non-NULL, falling back to simply printing to stderr if CTXT
114    is NULL.
115 
116    They have to be macros since they inject their "return" into the
117    function they are placed in.
118 
119    The variant macros express:
120 
121      (A) whether or not we need to return a value:
122 	    RETURN_VAL_IF_FAIL* vs
123 	    RETURN_IF_FAIL*,
124 	 with the former returning RETURN_EXPR, and
125 	    RETURN_NULL_IF_FAIL*
126 	 for the common case where a NULL value is to be returned on
127 	 error, and
128 
129      (B) whether the error message is to be directly printed:
130 	   RETURN_*IF_FAIL
131 	 or is a format string with some number of arguments:
132 	   RETURN_*IF_FAIL_PRINTF*
133 
134    They all use JIT_BEGIN_STMT/JIT_END_STMT so they can be written with
135    trailing semicolons.
136 */
137 
138 #define RETURN_VAL_IF_FAIL(TEST_EXPR, RETURN_EXPR, CTXT, LOC, ERR_MSG)	\
139   JIT_BEGIN_STMT							\
140     if (!(TEST_EXPR))							\
141       {								\
142 	jit_error ((CTXT), (LOC), "%s: %s", __func__, (ERR_MSG));	\
143 	return (RETURN_EXPR);						\
144       }								\
145   JIT_END_STMT
146 
147 #define RETURN_VAL_IF_FAIL_PRINTF1(TEST_EXPR, RETURN_EXPR, CTXT, LOC, ERR_FMT, A0) \
148   JIT_BEGIN_STMT							\
149     if (!(TEST_EXPR))							\
150       {								\
151 	jit_error ((CTXT), (LOC), "%s: " ERR_FMT,			\
152 		   __func__, (A0));				\
153 	return (RETURN_EXPR);						\
154       }								\
155   JIT_END_STMT
156 
157 #define RETURN_VAL_IF_FAIL_PRINTF2(TEST_EXPR, RETURN_EXPR, CTXT, LOC, ERR_FMT, A0, A1) \
158   JIT_BEGIN_STMT							\
159     if (!(TEST_EXPR))							\
160       {								\
161 	jit_error ((CTXT), (LOC), "%s: " ERR_FMT,				\
162 		   __func__, (A0), (A1));				\
163 	return (RETURN_EXPR);						\
164       }								\
165   JIT_END_STMT
166 
167 #define RETURN_VAL_IF_FAIL_PRINTF3(TEST_EXPR, RETURN_EXPR, CTXT, LOC, ERR_FMT, A0, A1, A2) \
168   JIT_BEGIN_STMT							\
169     if (!(TEST_EXPR))							\
170       {								\
171 	jit_error ((CTXT), (LOC), "%s: " ERR_FMT,				\
172 		   __func__, (A0), (A1), (A2));			\
173 	return (RETURN_EXPR);						\
174       }								\
175   JIT_END_STMT
176 
177 #define RETURN_VAL_IF_FAIL_PRINTF4(TEST_EXPR, RETURN_EXPR, CTXT, LOC, ERR_FMT, A0, A1, A2, A3) \
178   JIT_BEGIN_STMT							\
179     if (!(TEST_EXPR))							\
180       {								\
181 	jit_error ((CTXT), (LOC), "%s: " ERR_FMT,				\
182 		   __func__, (A0), (A1), (A2), (A3));			\
183 	return (RETURN_EXPR);						\
184       }								\
185   JIT_END_STMT
186 
187 #define RETURN_VAL_IF_FAIL_PRINTF5(TEST_EXPR, RETURN_EXPR, CTXT, LOC, ERR_FMT, A0, A1, A2, A3, A4) \
188   JIT_BEGIN_STMT							\
189     if (!(TEST_EXPR))							\
190       {								\
191 	jit_error ((CTXT), (LOC), "%s: " ERR_FMT,				\
192 		   __func__, (A0), (A1), (A2), (A3), (A4));	\
193 	return (RETURN_EXPR);						\
194       }								\
195   JIT_END_STMT
196 
197 #define RETURN_VAL_IF_FAIL_PRINTF6(TEST_EXPR, RETURN_EXPR, CTXT, LOC, ERR_FMT, A0, A1, A2, A3, A4, A5) \
198   JIT_BEGIN_STMT							\
199     if (!(TEST_EXPR))							\
200       {								\
201 	jit_error ((CTXT), (LOC), "%s: " ERR_FMT,				\
202 		   __func__, (A0), (A1), (A2), (A3), (A4), (A5));	\
203 	return (RETURN_EXPR);						\
204       }								\
205   JIT_END_STMT
206 
207 #define RETURN_NULL_IF_FAIL(TEST_EXPR, CTXT, LOC, ERR_MSG) \
208   RETURN_VAL_IF_FAIL ((TEST_EXPR), NULL, (CTXT), (LOC), (ERR_MSG))
209 
210 #define RETURN_NULL_IF_FAIL_PRINTF1(TEST_EXPR, CTXT, LOC, ERR_FMT, A0) \
211   RETURN_VAL_IF_FAIL_PRINTF1 (TEST_EXPR, NULL, CTXT, LOC, ERR_FMT, A0)
212 
213 #define RETURN_NULL_IF_FAIL_PRINTF2(TEST_EXPR, CTXT, LOC, ERR_FMT, A0, A1) \
214   RETURN_VAL_IF_FAIL_PRINTF2 (TEST_EXPR, NULL, CTXT, LOC, ERR_FMT, A0, A1)
215 
216 #define RETURN_NULL_IF_FAIL_PRINTF3(TEST_EXPR, CTXT, LOC, ERR_FMT, A0, A1, A2) \
217   RETURN_VAL_IF_FAIL_PRINTF3 (TEST_EXPR, NULL, CTXT, LOC, ERR_FMT, A0, A1, A2)
218 
219 #define RETURN_NULL_IF_FAIL_PRINTF4(TEST_EXPR, CTXT, LOC, ERR_FMT, A0, A1, A2, A3) \
220   RETURN_VAL_IF_FAIL_PRINTF4 (TEST_EXPR, NULL, CTXT, LOC, ERR_FMT, A0, A1, A2, A3)
221 
222 #define RETURN_NULL_IF_FAIL_PRINTF5(TEST_EXPR, CTXT, LOC, ERR_FMT, A0, A1, A2, A3, A4) \
223   RETURN_VAL_IF_FAIL_PRINTF5 (TEST_EXPR, NULL, CTXT, LOC, ERR_FMT, A0, A1, A2, A3, A4)
224 
225 #define RETURN_NULL_IF_FAIL_PRINTF6(TEST_EXPR, CTXT, LOC, ERR_FMT, A0, A1, A2, A3, A4, A5) \
226   RETURN_VAL_IF_FAIL_PRINTF6 (TEST_EXPR, NULL, CTXT, LOC, ERR_FMT, A0, A1, A2, A3, A4, A5)
227 
228 #define RETURN_IF_FAIL(TEST_EXPR, CTXT, LOC, ERR_MSG)			\
229   JIT_BEGIN_STMT							\
230     if (!(TEST_EXPR))							\
231       {								\
232 	jit_error ((CTXT), (LOC), "%s: %s", __func__, (ERR_MSG));		\
233 	return;							\
234       }								\
235   JIT_END_STMT
236 
237 #define RETURN_IF_FAIL_PRINTF1(TEST_EXPR, CTXT, LOC, ERR_FMT, A0) \
238   JIT_BEGIN_STMT							\
239     if (!(TEST_EXPR))							\
240       {								\
241 	jit_error ((CTXT), (LOC), "%s: " ERR_FMT,				\
242 		   __func__, (A0));					\
243 	return;							\
244       }								\
245   JIT_END_STMT
246 
247 #define RETURN_IF_FAIL_PRINTF2(TEST_EXPR, CTXT, LOC, ERR_FMT, A0, A1) \
248   JIT_BEGIN_STMT							\
249     if (!(TEST_EXPR))							\
250       {								\
251 	jit_error ((CTXT), (LOC), "%s: " ERR_FMT,				\
252 		   __func__, (A0), (A1));				\
253 	return;							\
254       }								\
255   JIT_END_STMT
256 
257 #define RETURN_IF_FAIL_PRINTF4(TEST_EXPR, CTXT, LOC, ERR_FMT, A0, A1, A2, A3) \
258   JIT_BEGIN_STMT							\
259     if (!(TEST_EXPR))							\
260       {								\
261 	jit_error ((CTXT), (LOC), "%s: " ERR_FMT,				\
262 		   __func__, (A0), (A1), (A2), (A3));			\
263 	return;							\
264       }								\
265   JIT_END_STMT
266 
267 /* Check that BLOCK is non-NULL, and that it's OK to add statements to
268    it.  This will fail if BLOCK has already been terminated by some
269    kind of jump or a return.  */
270 #define RETURN_IF_NOT_VALID_BLOCK(BLOCK, LOC)				\
271   JIT_BEGIN_STMT							\
272     RETURN_IF_FAIL ((BLOCK), NULL, (LOC), "NULL block");		\
273     RETURN_IF_FAIL_PRINTF2 (						\
274       !(BLOCK)->has_been_terminated (),				\
275       (BLOCK)->get_context (),						\
276       (LOC),								\
277       "adding to terminated block: %s (already terminated by: %s)",	\
278       (BLOCK)->get_debug_string (),					\
279       (BLOCK)->get_last_statement ()->get_debug_string ());		\
280   JIT_END_STMT
281 
282 /* As RETURN_IF_NOT_VALID_BLOCK, but injecting a "return NULL;" if it
283    fails.  */
284 #define RETURN_NULL_IF_NOT_VALID_BLOCK(BLOCK, LOC)			\
285   JIT_BEGIN_STMT							\
286     RETURN_NULL_IF_FAIL ((BLOCK), NULL, (LOC), "NULL block");		\
287     RETURN_NULL_IF_FAIL_PRINTF2 (					\
288       !(BLOCK)->has_been_terminated (),				\
289       (BLOCK)->get_context (),						\
290       (LOC),								\
291       "adding to terminated block: %s (already terminated by: %s)",	\
292       (BLOCK)->get_debug_string (),					\
293       (BLOCK)->get_last_statement ()->get_debug_string ());		\
294   JIT_END_STMT
295 
296 /* Format the given string, and report it as an error, either on CTXT
297    if non-NULL, or by printing to stderr if we have a NULL context.
298    LOC gives the source location where the error occcurred, and can be
299    NULL.  */
300 
301 static void
302 jit_error (gcc::jit::recording::context *ctxt,
303 	   gcc_jit_location *loc,
304 	   const char *fmt, ...)
305   GNU_PRINTF(3, 4);
306 
307 static void
jit_error(gcc::jit::recording::context * ctxt,gcc_jit_location * loc,const char * fmt,...)308 jit_error (gcc::jit::recording::context *ctxt,
309 	   gcc_jit_location *loc,
310 	   const char *fmt, ...)
311 {
312   va_list ap;
313   va_start (ap, fmt);
314 
315   if (ctxt)
316     ctxt->add_error_va (loc, fmt, ap);
317   else
318     {
319       /* No context?  Send to stderr.  */
320       vfprintf (stderr, fmt, ap);
321       fprintf (stderr, "\n");
322     }
323 
324   va_end (ap);
325 }
326 
327 /* Determine whether or not we can write to lvalues of type LTYPE from
328    rvalues of type RTYPE, detecting type errors such as attempting to
329    write to an int with a string literal (without an explicit cast).
330 
331    This is implemented by calling the
332    gcc::jit::recording::type::accepts_writes_from virtual function on
333    LTYPE.  */
334 
335 static bool
compatible_types(gcc::jit::recording::type * ltype,gcc::jit::recording::type * rtype)336 compatible_types (gcc::jit::recording::type *ltype,
337 		  gcc::jit::recording::type *rtype)
338 {
339   return ltype->accepts_writes_from (rtype);
340 }
341 
342 /* Public entrypoint for acquiring a gcc_jit_context.
343    Note that this creates a new top-level context; contrast with
344    gcc_jit_context_new_child_context below.
345 
346    The real work is done in the constructor for
347    gcc::jit::recording::context in jit-recording.c. */
348 
349 gcc_jit_context *
gcc_jit_context_acquire(void)350 gcc_jit_context_acquire (void)
351 {
352   gcc_jit_context *ctxt = new gcc_jit_context (NULL);
353   ctxt->log ("new top-level ctxt: %p", (void *)ctxt);
354   return ctxt;
355 }
356 
357 /* Public entrypoint for releasing a gcc_jit_context.
358    The real work is done in the destructor for
359    gcc::jit::recording::context in jit-recording.c.  */
360 
361 void
gcc_jit_context_release(gcc_jit_context * ctxt)362 gcc_jit_context_release (gcc_jit_context *ctxt)
363 {
364   RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL ctxt");
365   JIT_LOG_FUNC (ctxt->get_logger ());
366   ctxt->log ("deleting ctxt: %p", (void *)ctxt);
367   delete ctxt;
368 }
369 
370 /* Public entrypoint for creating a child context within
371    PARENT_CTXT.  See description in libgccjit.h.
372 
373    The real work is done in the constructor for
374    gcc::jit::recording::context in jit-recording.c. */
375 
376 gcc_jit_context *
gcc_jit_context_new_child_context(gcc_jit_context * parent_ctxt)377 gcc_jit_context_new_child_context (gcc_jit_context *parent_ctxt)
378 {
379   RETURN_NULL_IF_FAIL (parent_ctxt, NULL, NULL, "NULL parent ctxt");
380   JIT_LOG_FUNC (parent_ctxt->get_logger ());
381   parent_ctxt->log ("parent_ctxt: %p", (void *)parent_ctxt);
382   gcc_jit_context *child_ctxt = new gcc_jit_context (parent_ctxt);
383   child_ctxt->log ("new child_ctxt: %p", (void *)child_ctxt);
384   return child_ctxt;
385 }
386 
387 /* Public entrypoint.  See description in libgccjit.h.
388 
389    After error-checking, the real work is done by the
390      gcc::jit::recording::context::new_location
391    method in jit-recording.c.  */
392 
393 gcc_jit_location *
gcc_jit_context_new_location(gcc_jit_context * ctxt,const char * filename,int line,int column)394 gcc_jit_context_new_location (gcc_jit_context *ctxt,
395 			      const char *filename,
396 			      int line,
397 			      int column)
398 {
399   RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
400   JIT_LOG_FUNC (ctxt->get_logger ());
401   return (gcc_jit_location *)ctxt->new_location (filename, line, column, true);
402 }
403 
404 /* Public entrypoint.  See description in libgccjit.h.
405 
406    After error-checking, this calls the trivial
407    gcc::jit::recording::memento::as_object method (a location is a
408    memento), in jit-recording.h.  */
409 
410 gcc_jit_object *
gcc_jit_location_as_object(gcc_jit_location * loc)411 gcc_jit_location_as_object (gcc_jit_location *loc)
412 {
413   RETURN_NULL_IF_FAIL (loc, NULL, NULL, "NULL location");
414 
415   return static_cast <gcc_jit_object *> (loc->as_object ());
416 }
417 
418 /* Public entrypoint.  See description in libgccjit.h.
419 
420    After error-checking, this calls the trivial
421    gcc::jit::recording::memento::as_object method (a type is a
422    memento), in jit-recording.h.  */
423 
424 gcc_jit_object *
gcc_jit_type_as_object(gcc_jit_type * type)425 gcc_jit_type_as_object (gcc_jit_type *type)
426 {
427   RETURN_NULL_IF_FAIL (type, NULL, NULL, "NULL type");
428 
429   return static_cast <gcc_jit_object *> (type->as_object ());
430 }
431 
432 /* Public entrypoint for getting a specific type from a context.
433 
434    After error-checking, the real work is done by the
435    gcc::jit::recording::context::get_type method, in
436    jit-recording.c  */
437 
438 gcc_jit_type *
gcc_jit_context_get_type(gcc_jit_context * ctxt,enum gcc_jit_types type)439 gcc_jit_context_get_type (gcc_jit_context *ctxt,
440 			  enum gcc_jit_types type)
441 {
442   RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
443   JIT_LOG_FUNC (ctxt->get_logger ());
444   RETURN_NULL_IF_FAIL_PRINTF1 (
445     (type >= GCC_JIT_TYPE_VOID
446      && type <= GCC_JIT_TYPE_FILE_PTR),
447     ctxt, NULL,
448     "unrecognized value for enum gcc_jit_types: %i", type);
449 
450   return (gcc_jit_type *)ctxt->get_type (type);
451 }
452 
453 /* Public entrypoint for getting the integer type of the given size and
454    signedness.
455 
456    After error-checking, the real work is done by the
457    gcc::jit::recording::context::get_int_type method,
458    in jit-recording.c.  */
459 
460 gcc_jit_type *
gcc_jit_context_get_int_type(gcc_jit_context * ctxt,int num_bytes,int is_signed)461 gcc_jit_context_get_int_type (gcc_jit_context *ctxt,
462 			      int num_bytes, int is_signed)
463 {
464   RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
465   JIT_LOG_FUNC (ctxt->get_logger ());
466   RETURN_NULL_IF_FAIL (num_bytes >= 0, ctxt, NULL, "negative size");
467 
468   return (gcc_jit_type *)ctxt->get_int_type (num_bytes, is_signed);
469 }
470 
471 /* Public entrypoint.  See description in libgccjit.h.
472 
473    After error-checking, the real work is done by the
474    gcc::jit::recording::type::get_pointer method, in
475    jit-recording.c  */
476 
477 gcc_jit_type *
gcc_jit_type_get_pointer(gcc_jit_type * type)478 gcc_jit_type_get_pointer (gcc_jit_type *type)
479 {
480   RETURN_NULL_IF_FAIL (type, NULL, NULL, "NULL type");
481 
482   return (gcc_jit_type *)type->get_pointer ();
483 }
484 
485 /* Public entrypoint.  See description in libgccjit.h.
486 
487    After error-checking, the real work is done by the
488    gcc::jit::recording::type::get_const method, in
489    jit-recording.c.  */
490 
491 gcc_jit_type *
gcc_jit_type_get_const(gcc_jit_type * type)492 gcc_jit_type_get_const (gcc_jit_type *type)
493 {
494   RETURN_NULL_IF_FAIL (type, NULL, NULL, "NULL type");
495 
496   return (gcc_jit_type *)type->get_const ();
497 }
498 
499 /* Public entrypoint.  See description in libgccjit.h.
500 
501    After error-checking, the real work is done by the
502    gcc::jit::recording::type::get_volatile method, in
503    jit-recording.c.  */
504 
505 gcc_jit_type *
gcc_jit_type_get_volatile(gcc_jit_type * type)506 gcc_jit_type_get_volatile (gcc_jit_type *type)
507 {
508   RETURN_NULL_IF_FAIL (type, NULL, NULL, "NULL type");
509 
510   return (gcc_jit_type *)type->get_volatile ();
511 }
512 
513 /* Public entrypoint.  See description in libgccjit.h.
514 
515    After error-checking, the real work is done by the
516    gcc::jit::recording::context::new_array_type method, in
517    jit-recording.c.  */
518 
519 gcc_jit_type *
gcc_jit_context_new_array_type(gcc_jit_context * ctxt,gcc_jit_location * loc,gcc_jit_type * element_type,int num_elements)520 gcc_jit_context_new_array_type (gcc_jit_context *ctxt,
521 				gcc_jit_location *loc,
522 				gcc_jit_type *element_type,
523 				int num_elements)
524 {
525   RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
526   JIT_LOG_FUNC (ctxt->get_logger ());
527   /* LOC can be NULL.  */
528   RETURN_NULL_IF_FAIL (element_type, ctxt, loc, "NULL type");
529   RETURN_NULL_IF_FAIL (num_elements >= 0, ctxt, NULL, "negative size");
530 
531   return (gcc_jit_type *)ctxt->new_array_type (loc,
532 					       element_type,
533 					       num_elements);
534 }
535 
536 /* Public entrypoint.  See description in libgccjit.h.
537 
538    After error-checking, the real work is done by the
539    gcc::jit::recording::context::new_field method, in
540    jit-recording.c.  */
541 
542 gcc_jit_field *
gcc_jit_context_new_field(gcc_jit_context * ctxt,gcc_jit_location * loc,gcc_jit_type * type,const char * name)543 gcc_jit_context_new_field (gcc_jit_context *ctxt,
544 			   gcc_jit_location *loc,
545 			   gcc_jit_type *type,
546 			   const char *name)
547 {
548   RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
549   JIT_LOG_FUNC (ctxt->get_logger ());
550   /* LOC can be NULL.  */
551   RETURN_NULL_IF_FAIL (type, ctxt, loc, "NULL type");
552   RETURN_NULL_IF_FAIL (name, ctxt, loc, "NULL name");
553   RETURN_NULL_IF_FAIL_PRINTF2 (
554     type->has_known_size (),
555     ctxt, loc,
556     "unknown size for field \"%s\" (type: %s)",
557     name,
558     type->get_debug_string ());
559 
560   return (gcc_jit_field *)ctxt->new_field (loc, type, name);
561 }
562 
563 /* Public entrypoint.  See description in libgccjit.h.
564 
565    After error-checking, the real work is done by the
566    gcc::jit::recording::context::new_bitfield method, in
567    jit-recording.c.  */
568 
569 gcc_jit_field *
gcc_jit_context_new_bitfield(gcc_jit_context * ctxt,gcc_jit_location * loc,gcc_jit_type * type,int width,const char * name)570 gcc_jit_context_new_bitfield (gcc_jit_context *ctxt,
571 			      gcc_jit_location *loc,
572 			      gcc_jit_type *type,
573 			      int width,
574 			      const char *name)
575 {
576   RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
577   JIT_LOG_FUNC (ctxt->get_logger ());
578   /* LOC can be NULL.  */
579   RETURN_NULL_IF_FAIL (name, ctxt, loc, "NULL name");
580   RETURN_NULL_IF_FAIL (type, ctxt, loc, "NULL type");
581   RETURN_NULL_IF_FAIL_PRINTF2 (type->is_int () || type->is_bool (),
582 			       ctxt, loc,
583 			       "bit-field %s has non integral type %s",
584 			       name, type->get_debug_string ());
585   RETURN_NULL_IF_FAIL_PRINTF2 (
586     width > 0, ctxt, loc,
587     "invalid width %d for bitfield \"%s\" (must be > 0)",
588     width, name);
589   RETURN_NULL_IF_FAIL_PRINTF2 (
590     type->has_known_size (),
591     ctxt, loc,
592     "unknown size for field \"%s\" (type: %s)",
593     name,
594     type->get_debug_string ());
595 
596   return (gcc_jit_field *)ctxt->new_bitfield (loc, type, width, name);
597 }
598 
599 /* Public entrypoint.  See description in libgccjit.h.
600 
601    After error-checking, this calls the trivial
602    gcc::jit::recording::memento::as_object method (a field is a
603    memento), in jit-recording.h.  */
604 
605 gcc_jit_object *
gcc_jit_field_as_object(gcc_jit_field * field)606 gcc_jit_field_as_object (gcc_jit_field *field)
607 {
608   RETURN_NULL_IF_FAIL (field, NULL, NULL, "NULL field");
609 
610   return static_cast <gcc_jit_object *> (field->as_object ());
611 }
612 
613 /* Public entrypoint.  See description in libgccjit.h.
614 
615    After error-checking, the real work is done by the
616    gcc::jit::recording::context::new_struct_type method,
617    immediately followed by a "set_fields" call on the resulting
618    gcc::jit::recording::compound_type *, both in jit-recording.c  */
619 
620 gcc_jit_struct *
gcc_jit_context_new_struct_type(gcc_jit_context * ctxt,gcc_jit_location * loc,const char * name,int num_fields,gcc_jit_field ** fields)621 gcc_jit_context_new_struct_type (gcc_jit_context *ctxt,
622 				 gcc_jit_location *loc,
623 				 const char *name,
624 				 int num_fields,
625 				 gcc_jit_field **fields)
626 {
627   RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
628   JIT_LOG_FUNC (ctxt->get_logger ());
629   /* LOC can be NULL.  */
630   RETURN_NULL_IF_FAIL (name, ctxt, loc, "NULL name");
631   if (num_fields)
632     RETURN_NULL_IF_FAIL (fields, ctxt, loc, "NULL fields ptr");
633   for (int i = 0; i < num_fields; i++)
634     {
635       RETURN_NULL_IF_FAIL (fields[i], ctxt, loc, "NULL field ptr");
636       RETURN_NULL_IF_FAIL_PRINTF2 (
637 	fields[i]->get_container () == NULL,
638 	ctxt, loc,
639 	"%s is already a field of %s",
640 	fields[i]->get_debug_string (),
641 	fields[i]->get_container ()->get_debug_string ());
642     }
643 
644   gcc::jit::recording::struct_ *result =
645     ctxt->new_struct_type (loc, name);
646   result->set_fields (loc,
647 		      num_fields,
648 		      (gcc::jit::recording::field **)fields);
649   return static_cast<gcc_jit_struct *> (result);
650 }
651 
652 /* Public entrypoint.  See description in libgccjit.h.
653 
654    After error-checking, the real work is done by the
655    gcc::jit::recording::context::new_struct_type method in
656    jit-recording.c.  */
657 
658 gcc_jit_struct *
gcc_jit_context_new_opaque_struct(gcc_jit_context * ctxt,gcc_jit_location * loc,const char * name)659 gcc_jit_context_new_opaque_struct (gcc_jit_context *ctxt,
660 				   gcc_jit_location *loc,
661 				   const char *name)
662 {
663   RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
664   JIT_LOG_FUNC (ctxt->get_logger ());
665   /* LOC can be NULL.  */
666   RETURN_NULL_IF_FAIL (name, ctxt, loc, "NULL name");
667 
668   return (gcc_jit_struct *)ctxt->new_struct_type (loc, name);
669 }
670 
671 /* Public entrypoint.  See description in libgccjit.h.
672 
673    After error-checking, this calls the trivial
674    gcc::jit::recording::struct_::as_object method in
675    jit-recording.h.  */
676 
677 gcc_jit_type *
gcc_jit_struct_as_type(gcc_jit_struct * struct_type)678 gcc_jit_struct_as_type (gcc_jit_struct *struct_type)
679 {
680   RETURN_NULL_IF_FAIL (struct_type, NULL, NULL, "NULL struct_type");
681 
682   return static_cast <gcc_jit_type *> (struct_type->as_type ());
683 }
684 
685 /* Public entrypoint.  See description in libgccjit.h.
686 
687    After error-checking, the real work is done by the
688    gcc::jit::recording::compound_type::set_fields method in
689    jit-recording.c.  */
690 
691 void
gcc_jit_struct_set_fields(gcc_jit_struct * struct_type,gcc_jit_location * loc,int num_fields,gcc_jit_field ** fields)692 gcc_jit_struct_set_fields (gcc_jit_struct *struct_type,
693 			   gcc_jit_location *loc,
694 			   int num_fields,
695 			   gcc_jit_field **fields)
696 {
697   RETURN_IF_FAIL (struct_type, NULL, loc, "NULL struct_type");
698   gcc::jit::recording::context *ctxt = struct_type->m_ctxt;
699   JIT_LOG_FUNC (ctxt->get_logger ());
700   /* LOC can be NULL.  */
701   RETURN_IF_FAIL_PRINTF1 (
702     struct_type->get_fields () == NULL, ctxt, loc,
703     "%s already has had fields set",
704     struct_type->get_debug_string ());
705   if (num_fields)
706     RETURN_IF_FAIL (fields, ctxt, loc, "NULL fields ptr");
707   for (int i = 0; i < num_fields; i++)
708     {
709       RETURN_IF_FAIL_PRINTF2 (
710 	fields[i],
711 	ctxt, loc,
712 	"%s: NULL field ptr at index %i",
713 	struct_type->get_debug_string (),
714 	i);
715       RETURN_IF_FAIL_PRINTF2 (
716 	fields[i]->get_container () == NULL,
717 	ctxt, loc,
718 	"%s is already a field of %s",
719 	fields[i]->get_debug_string (),
720 	fields[i]->get_container ()->get_debug_string ());
721     }
722 
723   struct_type->set_fields (loc, num_fields,
724 			   (gcc::jit::recording::field **)fields);
725 }
726 
727 /* Public entrypoint.  See description in libgccjit.h.
728 
729    After error-checking, the real work is done by the
730    gcc::jit::recording::context::new_union_type method,
731    immediately followed by a "set_fields" call on the resulting
732    gcc::jit::recording::compound_type *, both in jit-recording.c  */
733 
734 gcc_jit_type *
gcc_jit_context_new_union_type(gcc_jit_context * ctxt,gcc_jit_location * loc,const char * name,int num_fields,gcc_jit_field ** fields)735 gcc_jit_context_new_union_type (gcc_jit_context *ctxt,
736 				gcc_jit_location *loc,
737 				const char *name,
738 				int num_fields,
739 				gcc_jit_field **fields)
740 {
741   RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
742   JIT_LOG_FUNC (ctxt->get_logger ());
743   /* LOC can be NULL.  */
744   RETURN_NULL_IF_FAIL (name, ctxt, loc, "NULL name");
745   if (num_fields)
746     RETURN_NULL_IF_FAIL (fields, ctxt, loc, "NULL fields ptr");
747   for (int i = 0; i < num_fields; i++)
748     {
749       RETURN_NULL_IF_FAIL (fields[i], ctxt, loc, "NULL field ptr");
750       RETURN_NULL_IF_FAIL_PRINTF2 (
751 	fields[i]->get_container () == NULL,
752 	ctxt, loc,
753 	"%s is already a field of %s",
754 	fields[i]->get_debug_string (),
755 	fields[i]->get_container ()->get_debug_string ());
756     }
757 
758   gcc::jit::recording::union_ *result =
759     ctxt->new_union_type (loc, name);
760   result->set_fields (loc,
761 		      num_fields,
762 		      (gcc::jit::recording::field **)fields);
763   return (gcc_jit_type *) (result);
764 }
765 
766 /* Public entrypoint.  See description in libgccjit.h.
767 
768    After error-checking, the real work is done by the
769    gcc::jit::recording::context::new_function_ptr_type method,
770    in jit-recording.c  */
771 
772 gcc_jit_type *
gcc_jit_context_new_function_ptr_type(gcc_jit_context * ctxt,gcc_jit_location * loc,gcc_jit_type * return_type,int num_params,gcc_jit_type ** param_types,int is_variadic)773 gcc_jit_context_new_function_ptr_type (gcc_jit_context *ctxt,
774 				       gcc_jit_location *loc,
775 				       gcc_jit_type *return_type,
776 				       int num_params,
777 				       gcc_jit_type **param_types,
778 				       int is_variadic)
779 {
780   RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
781   JIT_LOG_FUNC (ctxt->get_logger ());
782   /* LOC can be NULL.  */
783   RETURN_NULL_IF_FAIL (return_type, ctxt, loc, "NULL return_type");
784   RETURN_NULL_IF_FAIL (
785     (num_params == 0) || param_types,
786     ctxt, loc,
787     "NULL param_types creating function pointer type");
788   for (int i = 0; i < num_params; i++)
789     RETURN_NULL_IF_FAIL_PRINTF1 (
790       param_types[i],
791       ctxt, loc,
792       "NULL parameter type %i creating function pointer type", i);
793 
794   return (gcc_jit_type*)
795     ctxt->new_function_ptr_type (loc, return_type,
796 				 num_params,
797 				 (gcc::jit::recording::type **)param_types,
798 				 is_variadic);
799 }
800 
801 /* Constructing functions.  */
802 
803 /* Public entrypoint.  See description in libgccjit.h.
804 
805    After error-checking, the real work is done by the
806    gcc::jit::recording::context::new_param method, in jit-recording.c  */
807 
808 gcc_jit_param *
gcc_jit_context_new_param(gcc_jit_context * ctxt,gcc_jit_location * loc,gcc_jit_type * type,const char * name)809 gcc_jit_context_new_param (gcc_jit_context *ctxt,
810 			   gcc_jit_location *loc,
811 			   gcc_jit_type *type,
812 			   const char *name)
813 {
814   RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
815   JIT_LOG_FUNC (ctxt->get_logger ());
816   /* LOC can be NULL.  */
817   RETURN_NULL_IF_FAIL (type, ctxt, loc, "NULL type");
818   RETURN_NULL_IF_FAIL (name, ctxt, loc, "NULL name");
819 
820   return (gcc_jit_param *)ctxt->new_param (loc, type, name);
821 }
822 
823 /* Public entrypoint.  See description in libgccjit.h.
824 
825    After error-checking, this calls the trivial
826    gcc::jit::recording::memento::as_object method (a param is a memento),
827    in jit-recording.h.  */
828 
829 gcc_jit_object *
gcc_jit_param_as_object(gcc_jit_param * param)830 gcc_jit_param_as_object (gcc_jit_param *param)
831 {
832   RETURN_NULL_IF_FAIL (param, NULL, NULL, "NULL param");
833 
834   return static_cast <gcc_jit_object *> (param->as_object ());
835 }
836 
837 /* Public entrypoint.  See description in libgccjit.h.
838 
839    After error-checking, this calls the trivial
840    gcc::jit::recording::param::as_lvalue method in jit-recording.h.  */
841 
842 gcc_jit_lvalue *
gcc_jit_param_as_lvalue(gcc_jit_param * param)843 gcc_jit_param_as_lvalue (gcc_jit_param *param)
844 {
845   RETURN_NULL_IF_FAIL (param, NULL, NULL, "NULL param");
846 
847   return (gcc_jit_lvalue *)param->as_lvalue ();
848 }
849 
850 /* Public entrypoint.  See description in libgccjit.h.
851 
852    After error-checking, this calls the trivial
853    gcc::jit::recording::lvalue::as_rvalue method (a param is an rvalue),
854    in jit-recording.h.  */
855 
856 gcc_jit_rvalue *
gcc_jit_param_as_rvalue(gcc_jit_param * param)857 gcc_jit_param_as_rvalue (gcc_jit_param *param)
858 {
859   RETURN_NULL_IF_FAIL (param, NULL, NULL, "NULL param");
860 
861   return (gcc_jit_rvalue *)param->as_rvalue ();
862 }
863 
864 /* Public entrypoint.  See description in libgccjit.h.
865 
866    After error-checking, the real work is done by the
867    gcc::jit::recording::context::new_function method, in
868    jit-recording.c.  */
869 
870 gcc_jit_function *
gcc_jit_context_new_function(gcc_jit_context * ctxt,gcc_jit_location * loc,enum gcc_jit_function_kind kind,gcc_jit_type * return_type,const char * name,int num_params,gcc_jit_param ** params,int is_variadic)871 gcc_jit_context_new_function (gcc_jit_context *ctxt,
872 			      gcc_jit_location *loc,
873 			      enum gcc_jit_function_kind kind,
874 			      gcc_jit_type *return_type,
875 			      const char *name,
876 			      int num_params,
877 			      gcc_jit_param **params,
878 			      int is_variadic)
879 {
880   RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
881   JIT_LOG_FUNC (ctxt->get_logger ());
882   /* LOC can be NULL.  */
883   RETURN_NULL_IF_FAIL_PRINTF1 (
884     ((kind >= GCC_JIT_FUNCTION_EXPORTED)
885      && (kind <= GCC_JIT_FUNCTION_ALWAYS_INLINE)),
886     ctxt, loc,
887     "unrecognized value for enum gcc_jit_function_kind: %i",
888     kind);
889   RETURN_NULL_IF_FAIL (return_type, ctxt, loc, "NULL return_type");
890   RETURN_NULL_IF_FAIL (name, ctxt, loc, "NULL name");
891   /* The assembler can only handle certain names, so for now, enforce
892      C's rules for identiers upon the name, using ISALPHA and ISALNUM
893      from safe-ctype.h to ignore the current locale.
894      Eventually we'll need some way to interact with e.g. C++ name
895      mangling.  */
896   {
897     /* Leading char: */
898     char ch = *name;
899     RETURN_NULL_IF_FAIL_PRINTF2 (
900 	ISALPHA (ch) || ch == '_',
901 	ctxt, loc,
902 	"name \"%s\" contains invalid character: '%c'",
903 	name, ch);
904     /* Subsequent chars: */
905     for (const char *ptr = name + 1; (ch = *ptr); ptr++)
906       {
907 	RETURN_NULL_IF_FAIL_PRINTF2 (
908 	  ISALNUM (ch) || ch == '_',
909 	  ctxt, loc,
910 	  "name \"%s\" contains invalid character: '%c'",
911 	  name, ch);
912       }
913   }
914   RETURN_NULL_IF_FAIL_PRINTF1 (
915     (num_params == 0) || params,
916     ctxt, loc,
917     "NULL params creating function %s", name);
918   for (int i = 0; i < num_params; i++)
919     {
920       RETURN_NULL_IF_FAIL_PRINTF2 (
921 	params[i],
922 	ctxt, loc,
923 	"NULL parameter %i creating function %s", i, name);
924       RETURN_NULL_IF_FAIL_PRINTF5 (
925 	params[i]->get_scope () == NULL,
926 	ctxt, loc,
927 	"parameter %i \"%s\""
928 	" (type: %s)"
929 	" for function %s"
930 	" was already used for function %s",
931 	i, params[i]->get_debug_string (),
932 	params[i]->get_type ()->get_debug_string (),
933 	name,
934 	params[i]->get_scope ()->get_debug_string ());
935     }
936 
937   return (gcc_jit_function*)
938     ctxt->new_function (loc, kind, return_type, name,
939 			num_params,
940 			(gcc::jit::recording::param **)params,
941 			is_variadic,
942 			BUILT_IN_NONE);
943 }
944 
945 /* Public entrypoint.  See description in libgccjit.h.
946 
947    After error-checking, the real work is done by the
948    gcc::jit::recording::context::get_builtin_function method, in
949    jit-recording.c.  */
950 
951 gcc_jit_function *
gcc_jit_context_get_builtin_function(gcc_jit_context * ctxt,const char * name)952 gcc_jit_context_get_builtin_function (gcc_jit_context *ctxt,
953 				      const char *name)
954 {
955   RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
956   JIT_LOG_FUNC (ctxt->get_logger ());
957   RETURN_NULL_IF_FAIL (name, ctxt, NULL, "NULL name");
958 
959   return static_cast <gcc_jit_function *> (ctxt->get_builtin_function (name));
960 }
961 
962 /* Public entrypoint.  See description in libgccjit.h.
963 
964    After error-checking, this calls the trivial
965    gcc::jit::recording::memento::as_object method (a function is a
966    memento), in jit-recording.h.  */
967 
968 gcc_jit_object *
gcc_jit_function_as_object(gcc_jit_function * func)969 gcc_jit_function_as_object (gcc_jit_function *func)
970 {
971   RETURN_NULL_IF_FAIL (func, NULL, NULL, "NULL function");
972 
973   return static_cast <gcc_jit_object *> (func->as_object ());
974 }
975 
976 /* Public entrypoint.  See description in libgccjit.h.
977 
978    After error-checking, the real work is done by the
979    gcc::jit::recording::function::get_param method, in
980    jit-recording.h.  */
981 
982 gcc_jit_param *
gcc_jit_function_get_param(gcc_jit_function * func,int index)983 gcc_jit_function_get_param (gcc_jit_function *func, int index)
984 {
985   RETURN_NULL_IF_FAIL (func, NULL, NULL, "NULL function");
986   gcc::jit::recording::context *ctxt = func->m_ctxt;
987   JIT_LOG_FUNC (ctxt->get_logger ());
988   RETURN_NULL_IF_FAIL (index >= 0, ctxt, NULL, "negative index");
989   int num_params = func->get_params ().length ();
990   RETURN_NULL_IF_FAIL_PRINTF3 (index < num_params,
991 			       ctxt, NULL,
992 			       "index of %d is too large (%s has %d params)",
993 			       index,
994 			       func->get_debug_string (),
995 			       num_params);
996 
997   return static_cast <gcc_jit_param *> (func->get_param (index));
998 }
999 
1000 /* Public entrypoint.  See description in libgccjit.h.
1001 
1002    After error-checking, the real work is done by the
1003    gcc::jit::recording::function::dump_to_dot method, in
1004    jit-recording.c.  */
1005 
1006 void
gcc_jit_function_dump_to_dot(gcc_jit_function * func,const char * path)1007 gcc_jit_function_dump_to_dot (gcc_jit_function *func,
1008 			      const char *path)
1009 {
1010   RETURN_IF_FAIL (func, NULL, NULL, "NULL function");
1011   gcc::jit::recording::context *ctxt = func->m_ctxt;
1012   JIT_LOG_FUNC (ctxt->get_logger ());
1013   RETURN_IF_FAIL (path, ctxt, NULL, "NULL path");
1014 
1015   func->dump_to_dot (path);
1016 }
1017 
1018 /* Public entrypoint.  See description in libgccjit.h.
1019 
1020    After error-checking, the real work is done by the
1021    gcc::jit::recording::function::new_block method, in
1022    jit-recording.c.  */
1023 
1024 gcc_jit_block*
gcc_jit_function_new_block(gcc_jit_function * func,const char * name)1025 gcc_jit_function_new_block (gcc_jit_function *func,
1026 			    const char *name)
1027 {
1028   RETURN_NULL_IF_FAIL (func, NULL, NULL, "NULL function");
1029   JIT_LOG_FUNC (func->get_context ()->get_logger ());
1030   RETURN_NULL_IF_FAIL (func->get_kind () != GCC_JIT_FUNCTION_IMPORTED,
1031 		       func->get_context (), NULL,
1032 		       "cannot add block to an imported function");
1033   /* name can be NULL.  */
1034 
1035   return (gcc_jit_block *)func->new_block (name);
1036 }
1037 
1038 /* Public entrypoint.  See description in libgccjit.h.
1039 
1040    After error-checking, this calls the trivial
1041    gcc::jit::recording::memento::as_object method (a block is a
1042    memento), in jit-recording.h.  */
1043 
1044 gcc_jit_object *
gcc_jit_block_as_object(gcc_jit_block * block)1045 gcc_jit_block_as_object (gcc_jit_block *block)
1046 {
1047   RETURN_NULL_IF_FAIL (block, NULL, NULL, "NULL block");
1048 
1049   return static_cast <gcc_jit_object *> (block->as_object ());
1050 }
1051 
1052 /* Public entrypoint.  See description in libgccjit.h.
1053 
1054    After error-checking, the real work is done by the
1055    gcc::jit::recording::block::get_function method, in
1056    jit-recording.h.  */
1057 
1058 gcc_jit_function *
gcc_jit_block_get_function(gcc_jit_block * block)1059 gcc_jit_block_get_function (gcc_jit_block *block)
1060 {
1061   RETURN_NULL_IF_FAIL (block, NULL, NULL, "NULL block");
1062 
1063   return static_cast <gcc_jit_function *> (block->get_function ());
1064 }
1065 
1066 /* Public entrypoint.  See description in libgccjit.h.
1067 
1068    After error-checking, the real work is done by the
1069    gcc::jit::recording::context::new_global method, in
1070    jit-recording.c.  */
1071 
1072 gcc_jit_lvalue *
gcc_jit_context_new_global(gcc_jit_context * ctxt,gcc_jit_location * loc,enum gcc_jit_global_kind kind,gcc_jit_type * type,const char * name)1073 gcc_jit_context_new_global (gcc_jit_context *ctxt,
1074 			    gcc_jit_location *loc,
1075 			    enum gcc_jit_global_kind kind,
1076 			    gcc_jit_type *type,
1077 			    const char *name)
1078 {
1079   RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
1080   JIT_LOG_FUNC (ctxt->get_logger ());
1081   /* LOC can be NULL.  */
1082   RETURN_NULL_IF_FAIL_PRINTF1 (
1083     ((kind >= GCC_JIT_GLOBAL_EXPORTED)
1084      && (kind <= GCC_JIT_GLOBAL_IMPORTED)),
1085     ctxt, loc,
1086     "unrecognized value for enum gcc_jit_global_kind: %i",
1087     kind);
1088   RETURN_NULL_IF_FAIL (type, ctxt, loc, "NULL type");
1089   RETURN_NULL_IF_FAIL (name, ctxt, loc, "NULL name");
1090   RETURN_NULL_IF_FAIL_PRINTF2 (
1091     type->has_known_size (),
1092     ctxt, loc,
1093     "unknown size for global \"%s\" (type: %s)",
1094     name,
1095     type->get_debug_string ());
1096 
1097   return (gcc_jit_lvalue *)ctxt->new_global (loc, kind, type, name);
1098 }
1099 
1100 /* Public entrypoint.  See description in libgccjit.h.
1101 
1102    After error-checking, this calls the trivial
1103    gcc::jit::recording::memento::as_object method (an lvalue is a
1104    memento), in jit-recording.h.  */
1105 
1106 gcc_jit_object *
gcc_jit_lvalue_as_object(gcc_jit_lvalue * lvalue)1107 gcc_jit_lvalue_as_object (gcc_jit_lvalue *lvalue)
1108 {
1109   RETURN_NULL_IF_FAIL (lvalue, NULL, NULL, "NULL lvalue");
1110 
1111   return static_cast <gcc_jit_object *> (lvalue->as_object ());
1112 }
1113 
1114 /* Public entrypoint.  See description in libgccjit.h.
1115 
1116    After error-checking, this calls the trivial
1117    gcc::jit::recording::lvalue::as_rvalue method in jit-recording.h.  */
1118 
1119 gcc_jit_rvalue *
gcc_jit_lvalue_as_rvalue(gcc_jit_lvalue * lvalue)1120 gcc_jit_lvalue_as_rvalue (gcc_jit_lvalue *lvalue)
1121 {
1122   RETURN_NULL_IF_FAIL (lvalue, NULL, NULL, "NULL lvalue");
1123 
1124   return (gcc_jit_rvalue *)lvalue->as_rvalue ();
1125 }
1126 
1127 /* Public entrypoint.  See description in libgccjit.h.
1128 
1129    After error-checking, this calls the trivial
1130    gcc::jit::recording::memento::as_object method (an rvalue is a
1131    memento), in jit-recording.h.  */
1132 
1133 gcc_jit_object *
gcc_jit_rvalue_as_object(gcc_jit_rvalue * rvalue)1134 gcc_jit_rvalue_as_object (gcc_jit_rvalue *rvalue)
1135 {
1136   RETURN_NULL_IF_FAIL (rvalue, NULL, NULL, "NULL rvalue");
1137 
1138   return static_cast <gcc_jit_object *> (rvalue->as_object ());
1139 }
1140 
1141 /* Public entrypoint.  See description in libgccjit.h.
1142 
1143    After error-checking, the real work is done by the
1144    gcc::jit::recording::rvalue::get_type method, in
1145    jit-recording.h.  */
1146 
1147 gcc_jit_type *
gcc_jit_rvalue_get_type(gcc_jit_rvalue * rvalue)1148 gcc_jit_rvalue_get_type (gcc_jit_rvalue *rvalue)
1149 {
1150   RETURN_NULL_IF_FAIL (rvalue, NULL, NULL, "NULL rvalue");
1151 
1152   return static_cast <gcc_jit_type *> (rvalue->get_type ());
1153 }
1154 
1155 /* Verify that NUMERIC_TYPE is non-NULL, and that it is a "numeric"
1156    type i.e. it satisfies gcc::jit::type::is_numeric (), such as the
1157    result of gcc_jit_context_get_type (GCC_JIT_TYPE_INT).  */
1158 
1159 #define RETURN_NULL_IF_FAIL_NONNULL_NUMERIC_TYPE(CTXT, NUMERIC_TYPE) \
1160   JIT_BEGIN_STMT						     \
1161   RETURN_NULL_IF_FAIL (NUMERIC_TYPE, CTXT, NULL, "NULL type"); \
1162   RETURN_NULL_IF_FAIL_PRINTF1 (                                \
1163     NUMERIC_TYPE->is_numeric (), ctxt, NULL,                   \
1164     "not a numeric type: %s",                                  \
1165     NUMERIC_TYPE->get_debug_string ()); \
1166   JIT_END_STMT
1167 
1168 /* Public entrypoint.  See description in libgccjit.h.
1169 
1170    After error-checking, the real work is done by the
1171    gcc::jit::recording::context::new_rvalue_from_int method in
1172    jit-recording.c.  */
1173 
1174 gcc_jit_rvalue *
gcc_jit_context_new_rvalue_from_int(gcc_jit_context * ctxt,gcc_jit_type * numeric_type,int value)1175 gcc_jit_context_new_rvalue_from_int (gcc_jit_context *ctxt,
1176 				     gcc_jit_type *numeric_type,
1177 				     int value)
1178 {
1179   RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
1180   JIT_LOG_FUNC (ctxt->get_logger ());
1181   RETURN_NULL_IF_FAIL_NONNULL_NUMERIC_TYPE (ctxt, numeric_type);
1182 
1183   return ((gcc_jit_rvalue *)ctxt
1184 	  ->new_rvalue_from_const <int> (numeric_type, value));
1185 }
1186 
1187 /* FIXME. */
1188 
1189 gcc_jit_rvalue *
gcc_jit_context_new_rvalue_from_long(gcc_jit_context * ctxt,gcc_jit_type * numeric_type,long value)1190 gcc_jit_context_new_rvalue_from_long (gcc_jit_context *ctxt,
1191 				      gcc_jit_type *numeric_type,
1192 				      long value)
1193 {
1194   RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
1195   JIT_LOG_FUNC (ctxt->get_logger ());
1196   RETURN_NULL_IF_FAIL_NONNULL_NUMERIC_TYPE (ctxt, numeric_type);
1197 
1198   return ((gcc_jit_rvalue *)ctxt
1199 	  ->new_rvalue_from_const <long> (numeric_type, value));
1200 }
1201 
1202 /* Public entrypoint.  See description in libgccjit.h.
1203 
1204    This is essentially equivalent to:
1205       gcc_jit_context_new_rvalue_from_int (ctxt, numeric_type, 0);
1206    albeit with slightly different error messages if an error occurs.  */
1207 
1208 gcc_jit_rvalue *
gcc_jit_context_zero(gcc_jit_context * ctxt,gcc_jit_type * numeric_type)1209 gcc_jit_context_zero (gcc_jit_context *ctxt,
1210 		      gcc_jit_type *numeric_type)
1211 {
1212   RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
1213   JIT_LOG_FUNC (ctxt->get_logger ());
1214   RETURN_NULL_IF_FAIL_NONNULL_NUMERIC_TYPE (ctxt, numeric_type);
1215 
1216   return gcc_jit_context_new_rvalue_from_int (ctxt, numeric_type, 0);
1217 }
1218 
1219 /* Public entrypoint.  See description in libgccjit.h.
1220 
1221    This is essentially equivalent to:
1222       gcc_jit_context_new_rvalue_from_int (ctxt, numeric_type, 1);
1223    albeit with slightly different error messages if an error occurs.  */
1224 
1225 gcc_jit_rvalue *
gcc_jit_context_one(gcc_jit_context * ctxt,gcc_jit_type * numeric_type)1226 gcc_jit_context_one (gcc_jit_context *ctxt,
1227 		     gcc_jit_type *numeric_type)
1228 {
1229   RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
1230   JIT_LOG_FUNC (ctxt->get_logger ());
1231   RETURN_NULL_IF_FAIL_NONNULL_NUMERIC_TYPE (ctxt, numeric_type);
1232 
1233   return gcc_jit_context_new_rvalue_from_int (ctxt, numeric_type, 1);
1234 }
1235 
1236 /* Public entrypoint.  See description in libgccjit.h.
1237 
1238    After error-checking, the real work is done by the
1239    gcc::jit::recording::context::new_rvalue_from_double method in
1240    jit-recording.c.  */
1241 
1242 gcc_jit_rvalue *
gcc_jit_context_new_rvalue_from_double(gcc_jit_context * ctxt,gcc_jit_type * numeric_type,double value)1243 gcc_jit_context_new_rvalue_from_double (gcc_jit_context *ctxt,
1244 					gcc_jit_type *numeric_type,
1245 					double value)
1246 {
1247   RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
1248   JIT_LOG_FUNC (ctxt->get_logger ());
1249   RETURN_NULL_IF_FAIL_NONNULL_NUMERIC_TYPE (ctxt, numeric_type);
1250 
1251   return ((gcc_jit_rvalue *)ctxt
1252 	  ->new_rvalue_from_const <double> (numeric_type, value));
1253 }
1254 
1255 /* Public entrypoint.  See description in libgccjit.h.
1256 
1257    After error-checking, the real work is done by the
1258    gcc::jit::recording::context::new_rvalue_from_ptr method in
1259    jit-recording.c.  */
1260 
1261 gcc_jit_rvalue *
gcc_jit_context_new_rvalue_from_ptr(gcc_jit_context * ctxt,gcc_jit_type * pointer_type,void * value)1262 gcc_jit_context_new_rvalue_from_ptr (gcc_jit_context *ctxt,
1263 				     gcc_jit_type *pointer_type,
1264 				     void *value)
1265 {
1266   RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
1267   JIT_LOG_FUNC (ctxt->get_logger ());
1268   RETURN_NULL_IF_FAIL (pointer_type, ctxt, NULL, "NULL type");
1269   RETURN_NULL_IF_FAIL_PRINTF1 (
1270     pointer_type->is_pointer (),
1271     ctxt, NULL,
1272     "not a pointer type (type: %s)",
1273     pointer_type->get_debug_string ());
1274 
1275   return ((gcc_jit_rvalue *)ctxt
1276 	  ->new_rvalue_from_const <void *> (pointer_type, value));
1277 }
1278 
1279 /* Public entrypoint.  See description in libgccjit.h.
1280 
1281    This is essentially equivalent to:
1282       gcc_jit_context_new_rvalue_from_ptr (ctxt, pointer_type, NULL);
1283    albeit with slightly different error messages if an error occurs.  */
1284 
1285 gcc_jit_rvalue *
gcc_jit_context_null(gcc_jit_context * ctxt,gcc_jit_type * pointer_type)1286 gcc_jit_context_null (gcc_jit_context *ctxt,
1287 		      gcc_jit_type *pointer_type)
1288 {
1289   RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
1290   JIT_LOG_FUNC (ctxt->get_logger ());
1291   RETURN_NULL_IF_FAIL (pointer_type, ctxt, NULL, "NULL type");
1292   RETURN_NULL_IF_FAIL_PRINTF1 (
1293     pointer_type->is_pointer (),
1294     ctxt, NULL,
1295     "not a pointer type (type: %s)",
1296     pointer_type->get_debug_string ());
1297 
1298   return gcc_jit_context_new_rvalue_from_ptr (ctxt, pointer_type, NULL);
1299 }
1300 
1301 /* Public entrypoint.  See description in libgccjit.h.
1302 
1303    After error-checking, the real work is done by the
1304    gcc::jit::recording::context::new_string_literal method in
1305    jit-recording.c.  */
1306 
1307 gcc_jit_rvalue *
gcc_jit_context_new_string_literal(gcc_jit_context * ctxt,const char * value)1308 gcc_jit_context_new_string_literal (gcc_jit_context *ctxt,
1309 				    const char *value)
1310 {
1311   RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
1312   JIT_LOG_FUNC (ctxt->get_logger ());
1313   RETURN_NULL_IF_FAIL (value, ctxt, NULL, "NULL value");
1314 
1315   return (gcc_jit_rvalue *)ctxt->new_string_literal (value);
1316 }
1317 
1318 /* Public entrypoint.  See description in libgccjit.h.
1319 
1320    After error-checking, the real work is done by the
1321    gcc::jit::recording::context::new_unary_op method in
1322    jit-recording.c.  */
1323 
1324 gcc_jit_rvalue *
gcc_jit_context_new_unary_op(gcc_jit_context * ctxt,gcc_jit_location * loc,enum gcc_jit_unary_op op,gcc_jit_type * result_type,gcc_jit_rvalue * rvalue)1325 gcc_jit_context_new_unary_op (gcc_jit_context *ctxt,
1326 			      gcc_jit_location *loc,
1327 			      enum gcc_jit_unary_op op,
1328 			      gcc_jit_type *result_type,
1329 			      gcc_jit_rvalue *rvalue)
1330 {
1331   RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
1332   JIT_LOG_FUNC (ctxt->get_logger ());
1333   /* LOC can be NULL.  */
1334   RETURN_NULL_IF_FAIL_PRINTF1 (
1335     (op >= GCC_JIT_UNARY_OP_MINUS
1336      && op <= GCC_JIT_UNARY_OP_ABS),
1337     ctxt, loc,
1338     "unrecognized value for enum gcc_jit_unary_op: %i",
1339     op);
1340   RETURN_NULL_IF_FAIL (result_type, ctxt, loc, "NULL result_type");
1341   RETURN_NULL_IF_FAIL_PRINTF3 (
1342     result_type->is_numeric (), ctxt, loc,
1343     "gcc_jit_unary_op %s with operand %s "
1344     "has non-numeric result_type: %s",
1345     gcc::jit::unary_op_reproducer_strings[op],
1346     rvalue->get_debug_string (),
1347     result_type->get_debug_string ());
1348   RETURN_NULL_IF_FAIL (rvalue, ctxt, loc, "NULL rvalue");
1349 
1350   return (gcc_jit_rvalue *)ctxt->new_unary_op (loc, op, result_type, rvalue);
1351 }
1352 
1353 /* Determine if OP is a valid value for enum gcc_jit_binary_op.
1354    For use by both gcc_jit_context_new_binary_op and
1355    gcc_jit_block_add_assignment_op.  */
1356 
1357 static bool
valid_binary_op_p(enum gcc_jit_binary_op op)1358 valid_binary_op_p (enum gcc_jit_binary_op op)
1359 {
1360   return (op >= GCC_JIT_BINARY_OP_PLUS
1361 	  && op <= GCC_JIT_BINARY_OP_RSHIFT);
1362 }
1363 
1364 /* Public entrypoint.  See description in libgccjit.h.
1365 
1366    After error-checking, the real work is done by the
1367    gcc::jit::recording::context::new_binary_op method in
1368    jit-recording.c.  */
1369 
1370 gcc_jit_rvalue *
gcc_jit_context_new_binary_op(gcc_jit_context * ctxt,gcc_jit_location * loc,enum gcc_jit_binary_op op,gcc_jit_type * result_type,gcc_jit_rvalue * a,gcc_jit_rvalue * b)1371 gcc_jit_context_new_binary_op (gcc_jit_context *ctxt,
1372 			       gcc_jit_location *loc,
1373 			       enum gcc_jit_binary_op op,
1374 			       gcc_jit_type *result_type,
1375 			       gcc_jit_rvalue *a, gcc_jit_rvalue *b)
1376 {
1377   RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
1378   JIT_LOG_FUNC (ctxt->get_logger ());
1379   /* LOC can be NULL.  */
1380   RETURN_NULL_IF_FAIL_PRINTF1 (
1381     valid_binary_op_p (op),
1382     ctxt, loc,
1383     "unrecognized value for enum gcc_jit_binary_op: %i",
1384     op);
1385   RETURN_NULL_IF_FAIL (result_type, ctxt, loc, "NULL result_type");
1386   RETURN_NULL_IF_FAIL (a, ctxt, loc, "NULL a");
1387   RETURN_NULL_IF_FAIL (b, ctxt, loc, "NULL b");
1388   RETURN_NULL_IF_FAIL_PRINTF4 (
1389     a->get_type ()->unqualified () == b->get_type ()->unqualified (),
1390     ctxt, loc,
1391     "mismatching types for binary op:"
1392     " a: %s (type: %s) b: %s (type: %s)",
1393     a->get_debug_string (),
1394     a->get_type ()->get_debug_string (),
1395     b->get_debug_string (),
1396     b->get_type ()->get_debug_string ());
1397   RETURN_NULL_IF_FAIL_PRINTF4 (
1398     result_type->is_numeric (), ctxt, loc,
1399     "gcc_jit_binary_op %s with operands a: %s b: %s "
1400     "has non-numeric result_type: %s",
1401     gcc::jit::binary_op_reproducer_strings[op],
1402     a->get_debug_string (), b->get_debug_string (),
1403     result_type->get_debug_string ());
1404 
1405   return (gcc_jit_rvalue *)ctxt->new_binary_op (loc, op, result_type, a, b);
1406 }
1407 
1408 /* Public entrypoint.  See description in libgccjit.h.
1409 
1410    After error-checking, the real work is done by the
1411    gcc::jit::recording::context::new_comparison method in
1412    jit-recording.c.  */
1413 
1414 gcc_jit_rvalue *
gcc_jit_context_new_comparison(gcc_jit_context * ctxt,gcc_jit_location * loc,enum gcc_jit_comparison op,gcc_jit_rvalue * a,gcc_jit_rvalue * b)1415 gcc_jit_context_new_comparison (gcc_jit_context *ctxt,
1416 				gcc_jit_location *loc,
1417 				enum gcc_jit_comparison op,
1418 				gcc_jit_rvalue *a, gcc_jit_rvalue *b)
1419 {
1420   RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
1421   JIT_LOG_FUNC (ctxt->get_logger ());
1422   /* LOC can be NULL.  */
1423   RETURN_NULL_IF_FAIL_PRINTF1 (
1424     (op >= GCC_JIT_COMPARISON_EQ
1425      && op <= GCC_JIT_COMPARISON_GE),
1426     ctxt, loc,
1427     "unrecognized value for enum gcc_jit_comparison: %i",
1428     op);
1429   RETURN_NULL_IF_FAIL (a, ctxt, loc, "NULL a");
1430   RETURN_NULL_IF_FAIL (b, ctxt, loc, "NULL b");
1431   RETURN_NULL_IF_FAIL_PRINTF4 (
1432     a->get_type ()->unqualified () == b->get_type ()->unqualified (),
1433     ctxt, loc,
1434     "mismatching types for comparison:"
1435     " a: %s (type: %s) b: %s (type: %s)",
1436     a->get_debug_string (),
1437     a->get_type ()->get_debug_string (),
1438     b->get_debug_string (),
1439     b->get_type ()->get_debug_string ());
1440 
1441   return (gcc_jit_rvalue *)ctxt->new_comparison (loc, op, a, b);
1442 }
1443 
1444 /* Public entrypoint.  See description in libgccjit.h.
1445 
1446    After error-checking, the real work is done by the
1447    gcc::jit::recording::context::new_call method in
1448    jit-recording.c.  */
1449 
1450 gcc_jit_rvalue *
gcc_jit_context_new_call(gcc_jit_context * ctxt,gcc_jit_location * loc,gcc_jit_function * func,int numargs,gcc_jit_rvalue ** args)1451 gcc_jit_context_new_call (gcc_jit_context *ctxt,
1452 			  gcc_jit_location *loc,
1453 			  gcc_jit_function *func,
1454 			  int numargs , gcc_jit_rvalue **args)
1455 {
1456   RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
1457   JIT_LOG_FUNC (ctxt->get_logger ());
1458   /* LOC can be NULL.  */
1459   RETURN_NULL_IF_FAIL (func, ctxt, loc, "NULL function");
1460   if (numargs)
1461     RETURN_NULL_IF_FAIL (args, ctxt, loc, "NULL args");
1462 
1463   int min_num_params = func->get_params ().length ();
1464   bool is_variadic = func->is_variadic ();
1465 
1466   RETURN_NULL_IF_FAIL_PRINTF3 (
1467     numargs >= min_num_params,
1468     ctxt, loc,
1469     "not enough arguments to function \"%s\""
1470     " (got %i args, expected %i)",
1471     func->get_name ()->c_str (),
1472     numargs, min_num_params);
1473 
1474   RETURN_NULL_IF_FAIL_PRINTF3 (
1475     (numargs == min_num_params || is_variadic),
1476     ctxt, loc,
1477     "too many arguments to function \"%s\""
1478     " (got %i args, expected %i)",
1479     func->get_name ()->c_str (),
1480     numargs, min_num_params);
1481 
1482   for (int i = 0; i < min_num_params; i++)
1483     {
1484       gcc::jit::recording::param *param = func->get_param (i);
1485       gcc_jit_rvalue *arg = args[i];
1486 
1487       RETURN_NULL_IF_FAIL_PRINTF4 (
1488 	arg,
1489 	ctxt, loc,
1490 	"NULL argument %i to function \"%s\":"
1491 	" param %s (type: %s)",
1492 	i + 1,
1493 	func->get_name ()->c_str (),
1494 	param->get_debug_string (),
1495 	param->get_type ()->get_debug_string ());
1496 
1497       RETURN_NULL_IF_FAIL_PRINTF6 (
1498 	compatible_types (param->get_type (),
1499 			  arg->get_type ()),
1500 	ctxt, loc,
1501 	"mismatching types for argument %d of function \"%s\":"
1502 	" assignment to param %s (type: %s) from %s (type: %s)",
1503 	i + 1,
1504 	func->get_name ()->c_str (),
1505 	param->get_debug_string (),
1506 	param->get_type ()->get_debug_string (),
1507 	arg->get_debug_string (),
1508 	arg->get_type ()->get_debug_string ());
1509     }
1510 
1511   return (gcc_jit_rvalue *)ctxt->new_call (loc,
1512 					   func,
1513 					   numargs,
1514 					   (gcc::jit::recording::rvalue **)args);
1515 }
1516 
1517 /* Public entrypoint.  See description in libgccjit.h.
1518 
1519    After error-checking, the real work is done by the
1520    gcc::jit::recording::context::new_call_through_ptr method in
1521    jit-recording.c.  */
1522 
1523 gcc_jit_rvalue *
gcc_jit_context_new_call_through_ptr(gcc_jit_context * ctxt,gcc_jit_location * loc,gcc_jit_rvalue * fn_ptr,int numargs,gcc_jit_rvalue ** args)1524 gcc_jit_context_new_call_through_ptr (gcc_jit_context *ctxt,
1525 				      gcc_jit_location *loc,
1526 				      gcc_jit_rvalue *fn_ptr,
1527 				      int numargs, gcc_jit_rvalue **args)
1528 {
1529   RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
1530   JIT_LOG_FUNC (ctxt->get_logger ());
1531   /* LOC can be NULL.  */
1532   RETURN_NULL_IF_FAIL (fn_ptr, ctxt, loc, "NULL fn_ptr");
1533   if (numargs)
1534     RETURN_NULL_IF_FAIL (args, ctxt, loc, "NULL args");
1535 
1536   gcc::jit::recording::type *ptr_type = fn_ptr->get_type ()->dereference ();
1537   RETURN_NULL_IF_FAIL_PRINTF2 (
1538     ptr_type, ctxt, loc,
1539     "fn_ptr is not a ptr: %s"
1540     " type: %s",
1541     fn_ptr->get_debug_string (),
1542     fn_ptr->get_type ()->get_debug_string ());
1543 
1544   gcc::jit::recording::function_type *fn_type =
1545     ptr_type->dyn_cast_function_type();
1546   RETURN_NULL_IF_FAIL_PRINTF2 (
1547     fn_type, ctxt, loc,
1548     "fn_ptr is not a function ptr: %s"
1549     " type: %s",
1550     fn_ptr->get_debug_string (),
1551     fn_ptr->get_type ()->get_debug_string ());
1552 
1553   int min_num_params = fn_type->get_param_types ().length ();
1554   bool is_variadic = fn_type->is_variadic ();
1555 
1556   RETURN_NULL_IF_FAIL_PRINTF3 (
1557     numargs >= min_num_params,
1558     ctxt, loc,
1559     "not enough arguments to fn_ptr: %s"
1560     " (got %i args, expected %i)",
1561     fn_ptr->get_debug_string (),
1562     numargs, min_num_params);
1563 
1564   RETURN_NULL_IF_FAIL_PRINTF3 (
1565     (numargs == min_num_params || is_variadic),
1566     ctxt, loc,
1567     "too many arguments to fn_ptr: %s"
1568     " (got %i args, expected %i)",
1569     fn_ptr->get_debug_string (),
1570     numargs, min_num_params);
1571 
1572   for (int i = 0; i < min_num_params; i++)
1573     {
1574       gcc::jit::recording::type *param_type = fn_type->get_param_types ()[i];
1575       gcc_jit_rvalue *arg = args[i];
1576 
1577       RETURN_NULL_IF_FAIL_PRINTF3 (
1578 	arg,
1579 	ctxt, loc,
1580 	"NULL argument %i to fn_ptr: %s"
1581 	" (type: %s)",
1582 	i + 1,
1583 	fn_ptr->get_debug_string (),
1584 	param_type->get_debug_string ());
1585 
1586       RETURN_NULL_IF_FAIL_PRINTF6 (
1587 	compatible_types (param_type,
1588 			  arg->get_type ()),
1589 	ctxt, loc,
1590 	"mismatching types for argument %d of fn_ptr: %s:"
1591 	" assignment to param %d (type: %s) from %s (type: %s)",
1592 	i + 1,
1593 	fn_ptr->get_debug_string (),
1594 	i + 1,
1595 	param_type->get_debug_string (),
1596 	arg->get_debug_string (),
1597 	arg->get_type ()->get_debug_string ());
1598     }
1599 
1600   return (gcc_jit_rvalue *)(
1601 	    ctxt->new_call_through_ptr (loc,
1602 					fn_ptr,
1603 					numargs,
1604 					(gcc::jit::recording::rvalue **)args));
1605 }
1606 
1607 /* Helper function for determining if we can cast an rvalue from SRC_TYPE
1608    to DST_TYPE, for use by gcc_jit_context_new_cast.
1609 
1610    We only permit these kinds of cast:
1611 
1612      int <-> float
1613      int <-> bool
1614      P*  <-> Q*   for pointer types P and Q.  */
1615 
1616 static bool
is_valid_cast(gcc::jit::recording::type * src_type,gcc_jit_type * dst_type)1617 is_valid_cast (gcc::jit::recording::type *src_type,
1618 	       gcc_jit_type *dst_type)
1619 {
1620   bool src_is_int = src_type->is_int ();
1621   bool dst_is_int = dst_type->is_int ();
1622   bool src_is_float = src_type->is_float ();
1623   bool dst_is_float = dst_type->is_float ();
1624   bool src_is_bool = src_type->is_bool ();
1625   bool dst_is_bool = dst_type->is_bool ();
1626 
1627   if (src_is_int)
1628     if (dst_is_int || dst_is_float || dst_is_bool)
1629       return true;
1630 
1631   if (src_is_float)
1632     if (dst_is_int || dst_is_float)
1633       return true;
1634 
1635   if (src_is_bool)
1636     if (dst_is_int || dst_is_bool)
1637       return true;
1638 
1639   /* Permit casts between pointer types.  */
1640   gcc::jit::recording::type *deref_src_type = src_type->is_pointer ();
1641   gcc::jit::recording::type *deref_dst_type = dst_type->is_pointer ();
1642   if (deref_src_type && deref_dst_type)
1643     return true;
1644 
1645   return false;
1646 }
1647 
1648 /* Public entrypoint.  See description in libgccjit.h.
1649 
1650    After error-checking, the real work is done by the
1651    gcc::jit::recording::context::new_cast method in jit-recording.c.  */
1652 
1653 gcc_jit_rvalue *
gcc_jit_context_new_cast(gcc_jit_context * ctxt,gcc_jit_location * loc,gcc_jit_rvalue * rvalue,gcc_jit_type * type)1654 gcc_jit_context_new_cast (gcc_jit_context *ctxt,
1655 			  gcc_jit_location *loc,
1656 			  gcc_jit_rvalue *rvalue,
1657 			  gcc_jit_type *type)
1658 {
1659   RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
1660   JIT_LOG_FUNC (ctxt->get_logger ());
1661   /* LOC can be NULL.  */
1662   RETURN_NULL_IF_FAIL (rvalue, ctxt, loc, "NULL rvalue");
1663   RETURN_NULL_IF_FAIL (type, ctxt, loc, "NULL type");
1664   RETURN_NULL_IF_FAIL_PRINTF3 (
1665     is_valid_cast (rvalue->get_type (), type),
1666     ctxt, loc,
1667     "cannot cast %s from type: %s to type: %s",
1668     rvalue->get_debug_string (),
1669     rvalue->get_type ()->get_debug_string (),
1670     type->get_debug_string ());
1671 
1672   return static_cast <gcc_jit_rvalue *> (ctxt->new_cast (loc, rvalue, type));
1673 }
1674 
1675 /* Public entrypoint.  See description in libgccjit.h.
1676 
1677    After error-checking, the real work is done by the
1678    gcc::jit::recording::context::new_array_access method in
1679    jit-recording.c.  */
1680 
1681 extern gcc_jit_lvalue *
gcc_jit_context_new_array_access(gcc_jit_context * ctxt,gcc_jit_location * loc,gcc_jit_rvalue * ptr,gcc_jit_rvalue * index)1682 gcc_jit_context_new_array_access (gcc_jit_context *ctxt,
1683 				  gcc_jit_location *loc,
1684 				  gcc_jit_rvalue *ptr,
1685 				  gcc_jit_rvalue *index)
1686 {
1687   RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
1688   JIT_LOG_FUNC (ctxt->get_logger ());
1689   /* LOC can be NULL.  */
1690   RETURN_NULL_IF_FAIL (ptr, ctxt, loc, "NULL ptr");
1691   RETURN_NULL_IF_FAIL (index, ctxt, loc, "NULL index");
1692   RETURN_NULL_IF_FAIL_PRINTF2 (
1693     ptr->get_type ()->dereference (),
1694     ctxt, loc,
1695     "ptr: %s (type: %s) is not a pointer or array",
1696     ptr->get_debug_string (),
1697     ptr->get_type ()->get_debug_string ());
1698   RETURN_NULL_IF_FAIL_PRINTF2 (
1699     index->get_type ()->is_numeric (),
1700     ctxt, loc,
1701     "index: %s (type: %s) is not of numeric type",
1702     index->get_debug_string (),
1703     index->get_type ()->get_debug_string ());
1704 
1705   return (gcc_jit_lvalue *)ctxt->new_array_access (loc, ptr, index);
1706 }
1707 
1708 /* Public entrypoint.  See description in libgccjit.h.
1709 
1710    After error-checking, the real work is done by the
1711    gcc::jit::recording::memento::get_context method in
1712    jit-recording.h.  */
1713 
1714 gcc_jit_context *
gcc_jit_object_get_context(gcc_jit_object * obj)1715 gcc_jit_object_get_context (gcc_jit_object *obj)
1716 {
1717   RETURN_NULL_IF_FAIL (obj, NULL, NULL, "NULL object");
1718 
1719   return static_cast <gcc_jit_context *> (obj->get_context ());
1720 }
1721 
1722 /* Public entrypoint.  See description in libgccjit.h.
1723 
1724    After error-checking, the real work is done by the
1725    gcc::jit::recording::memento::get_debug_string method in
1726    jit-recording.c.  */
1727 
1728 const char *
gcc_jit_object_get_debug_string(gcc_jit_object * obj)1729 gcc_jit_object_get_debug_string (gcc_jit_object *obj)
1730 {
1731   RETURN_NULL_IF_FAIL (obj, NULL, NULL, "NULL object");
1732 
1733   return obj->get_debug_string ();
1734 }
1735 
1736 /* Public entrypoint.  See description in libgccjit.h.
1737 
1738    After error-checking, the real work is done by the
1739    gcc::jit::recording::lvalue::access_field method in
1740    jit-recording.c.  */
1741 
1742 gcc_jit_lvalue *
gcc_jit_lvalue_access_field(gcc_jit_lvalue * struct_,gcc_jit_location * loc,gcc_jit_field * field)1743 gcc_jit_lvalue_access_field (gcc_jit_lvalue *struct_,
1744 			     gcc_jit_location *loc,
1745 			     gcc_jit_field *field)
1746 {
1747   RETURN_NULL_IF_FAIL (struct_, NULL, loc, "NULL struct");
1748   gcc::jit::recording::context *ctxt = struct_->m_ctxt;
1749   JIT_LOG_FUNC (ctxt->get_logger ());
1750   /* LOC can be NULL.  */
1751   RETURN_NULL_IF_FAIL (field, ctxt, loc, "NULL field");
1752   RETURN_NULL_IF_FAIL_PRINTF1 (field->get_container (), field->m_ctxt, loc,
1753 			       "field %s has not been placed in a struct",
1754 			       field->get_debug_string ());
1755   gcc::jit::recording::type *underlying_type =
1756     struct_->get_type ();
1757   RETURN_NULL_IF_FAIL_PRINTF2 (
1758     (field->get_container ()->unqualified ()
1759      == underlying_type->unqualified ()),
1760     struct_->m_ctxt, loc,
1761     "%s is not a field of %s",
1762     field->get_debug_string (),
1763     underlying_type->get_debug_string ());
1764 
1765   return (gcc_jit_lvalue *)struct_->access_field (loc, field);
1766 }
1767 
1768 /* Public entrypoint.  See description in libgccjit.h.
1769 
1770    After error-checking, the real work is done by the
1771    gcc::jit::recording::rvalue::access_field method in
1772    jit-recording.c.  */
1773 
1774 gcc_jit_rvalue *
gcc_jit_rvalue_access_field(gcc_jit_rvalue * struct_,gcc_jit_location * loc,gcc_jit_field * field)1775 gcc_jit_rvalue_access_field (gcc_jit_rvalue *struct_,
1776 			     gcc_jit_location *loc,
1777 			     gcc_jit_field *field)
1778 {
1779   RETURN_NULL_IF_FAIL (struct_, NULL, loc, "NULL struct");
1780   gcc::jit::recording::context *ctxt = struct_->m_ctxt;
1781   JIT_LOG_FUNC (ctxt->get_logger ());
1782   /* LOC can be NULL.  */
1783   RETURN_NULL_IF_FAIL (field, ctxt, loc, "NULL field");
1784   RETURN_NULL_IF_FAIL_PRINTF1 (field->get_container (), field->m_ctxt, loc,
1785 			       "field %s has not been placed in a struct",
1786 			       field->get_debug_string ());
1787   gcc::jit::recording::type *underlying_type =
1788     struct_->get_type ();
1789   RETURN_NULL_IF_FAIL_PRINTF2 (
1790     (field->get_container ()->unqualified ()
1791      == underlying_type->unqualified ()),
1792     struct_->m_ctxt, loc,
1793     "%s is not a field of %s",
1794     field->get_debug_string (),
1795     underlying_type->get_debug_string ());
1796 
1797   return (gcc_jit_rvalue *)struct_->access_field (loc, field);
1798 }
1799 
1800 /* Public entrypoint.  See description in libgccjit.h.
1801 
1802    After error-checking, the real work is done by the
1803    gcc::jit::recording::rvalue::deference_field method in
1804    jit-recording.c.  */
1805 
1806 gcc_jit_lvalue *
gcc_jit_rvalue_dereference_field(gcc_jit_rvalue * ptr,gcc_jit_location * loc,gcc_jit_field * field)1807 gcc_jit_rvalue_dereference_field (gcc_jit_rvalue *ptr,
1808 				  gcc_jit_location *loc,
1809 				  gcc_jit_field *field)
1810 {
1811   RETURN_NULL_IF_FAIL (ptr, NULL, loc, "NULL ptr");
1812   JIT_LOG_FUNC (ptr->get_context ()->get_logger ());
1813   /* LOC can be NULL.  */
1814   RETURN_NULL_IF_FAIL (field, NULL, loc, "NULL field");
1815   gcc::jit::recording::type *underlying_type =
1816     ptr->get_type ()->is_pointer ();
1817   RETURN_NULL_IF_FAIL_PRINTF1 (field->get_container (), field->m_ctxt, loc,
1818 			       "field %s has not been placed in a struct",
1819 			       field->get_debug_string ());
1820   RETURN_NULL_IF_FAIL_PRINTF3 (
1821     underlying_type,
1822     ptr->m_ctxt, loc,
1823     "dereference of non-pointer %s (type: %s) when accessing ->%s",
1824     ptr->get_debug_string (),
1825     ptr->get_type ()->get_debug_string (),
1826     field->get_debug_string ());
1827   RETURN_NULL_IF_FAIL_PRINTF2 (
1828     (field->get_container ()->unqualified ()
1829      == underlying_type->unqualified ()),
1830     ptr->m_ctxt, loc,
1831     "%s is not a field of %s",
1832     field->get_debug_string (),
1833     underlying_type->get_debug_string ());
1834 
1835   return (gcc_jit_lvalue *)ptr->dereference_field (loc, field);
1836 }
1837 
1838 /* Public entrypoint.  See description in libgccjit.h.
1839 
1840    After error-checking, the real work is done by the
1841    gcc::jit::recording::rvalue::deference method in
1842    jit-recording.c.  */
1843 
1844 gcc_jit_lvalue *
gcc_jit_rvalue_dereference(gcc_jit_rvalue * rvalue,gcc_jit_location * loc)1845 gcc_jit_rvalue_dereference (gcc_jit_rvalue *rvalue,
1846 			    gcc_jit_location *loc)
1847 {
1848   RETURN_NULL_IF_FAIL (rvalue, NULL, loc, "NULL rvalue");
1849   JIT_LOG_FUNC (rvalue->get_context ()->get_logger ());
1850   /* LOC can be NULL.  */
1851 
1852   gcc::jit::recording::type *underlying_type =
1853     rvalue->get_type ()->is_pointer ();
1854 
1855   RETURN_NULL_IF_FAIL_PRINTF2 (
1856     underlying_type,
1857     rvalue->m_ctxt, loc,
1858     "dereference of non-pointer %s (type: %s)",
1859     rvalue->get_debug_string (),
1860     rvalue->get_type ()->get_debug_string ());
1861 
1862   RETURN_NULL_IF_FAIL_PRINTF2 (
1863     !underlying_type->is_void (),
1864     rvalue->m_ctxt, loc,
1865     "dereference of void pointer %s (type: %s)",
1866     rvalue->get_debug_string (),
1867     rvalue->get_type ()->get_debug_string ());
1868 
1869   return (gcc_jit_lvalue *)rvalue->dereference (loc);
1870 }
1871 
1872 /* Public entrypoint.  See description in libgccjit.h.
1873 
1874    After error-checking, the real work is done by the
1875    gcc::jit::recording::lvalue::get_address method in jit-recording.c.  */
1876 
1877 gcc_jit_rvalue *
gcc_jit_lvalue_get_address(gcc_jit_lvalue * lvalue,gcc_jit_location * loc)1878 gcc_jit_lvalue_get_address (gcc_jit_lvalue *lvalue,
1879 			    gcc_jit_location *loc)
1880 {
1881   RETURN_NULL_IF_FAIL (lvalue, NULL, loc, "NULL lvalue");
1882   JIT_LOG_FUNC (lvalue->get_context ()->get_logger ());
1883   /* LOC can be NULL.  */
1884 
1885   return (gcc_jit_rvalue *)lvalue->get_address (loc);
1886 }
1887 
1888 /* Public entrypoint.  See description in libgccjit.h.
1889 
1890    After error-checking, the real work is done by the
1891    gcc::jit::recording::function::new_local method in jit-recording.c.  */
1892 
1893 gcc_jit_lvalue *
gcc_jit_function_new_local(gcc_jit_function * func,gcc_jit_location * loc,gcc_jit_type * type,const char * name)1894 gcc_jit_function_new_local (gcc_jit_function *func,
1895 			    gcc_jit_location *loc,
1896 			    gcc_jit_type *type,
1897 			    const char *name)
1898 {
1899   RETURN_NULL_IF_FAIL (func, NULL, loc, "NULL function");
1900   gcc::jit::recording::context *ctxt = func->m_ctxt;
1901   JIT_LOG_FUNC (ctxt->get_logger ());
1902   /* LOC can be NULL.  */
1903   RETURN_NULL_IF_FAIL (func->get_kind () != GCC_JIT_FUNCTION_IMPORTED,
1904 		       ctxt, loc,
1905 		       "Cannot add locals to an imported function");
1906   RETURN_NULL_IF_FAIL (type, ctxt, loc, "NULL type");
1907   RETURN_NULL_IF_FAIL (name, ctxt, loc, "NULL name");
1908   RETURN_NULL_IF_FAIL_PRINTF2 (
1909     type->has_known_size (),
1910     ctxt, loc,
1911     "unknown size for local \"%s\" (type: %s)",
1912     name,
1913     type->get_debug_string ());
1914 
1915   return (gcc_jit_lvalue *)func->new_local (loc, type, name);
1916 }
1917 
1918 /* Public entrypoint.  See description in libgccjit.h.
1919 
1920    After error-checking, the real work is done by the
1921    gcc::jit::recording::block::add_eval method in jit-recording.c.  */
1922 
1923 void
gcc_jit_block_add_eval(gcc_jit_block * block,gcc_jit_location * loc,gcc_jit_rvalue * rvalue)1924 gcc_jit_block_add_eval (gcc_jit_block *block,
1925 			gcc_jit_location *loc,
1926 			gcc_jit_rvalue *rvalue)
1927 {
1928   RETURN_IF_NOT_VALID_BLOCK (block, loc);
1929   gcc::jit::recording::context *ctxt = block->get_context ();
1930   JIT_LOG_FUNC (ctxt->get_logger ());
1931   /* LOC can be NULL.  */
1932   RETURN_IF_FAIL (rvalue, ctxt, loc, "NULL rvalue");
1933 
1934   gcc::jit::recording::statement *stmt = block->add_eval (loc, rvalue);
1935 
1936   /* "stmt" should be good enough to be usable in error-messages,
1937      but might still not be compilable; perform some more
1938      error-checking here.  We do this here so that the error messages
1939      can contain a stringified version of "stmt", whilst appearing
1940      as close as possible to the point of failure.  */
1941   rvalue->verify_valid_within_stmt (__func__, stmt);
1942 }
1943 
1944 /* Public entrypoint.  See description in libgccjit.h.
1945 
1946    After error-checking, the real work is done by the
1947    gcc::jit::recording::block::add_assignment method in
1948    jit-recording.c.  */
1949 
1950 void
gcc_jit_block_add_assignment(gcc_jit_block * block,gcc_jit_location * loc,gcc_jit_lvalue * lvalue,gcc_jit_rvalue * rvalue)1951 gcc_jit_block_add_assignment (gcc_jit_block *block,
1952 			      gcc_jit_location *loc,
1953 			      gcc_jit_lvalue *lvalue,
1954 			      gcc_jit_rvalue *rvalue)
1955 {
1956   RETURN_IF_NOT_VALID_BLOCK (block, loc);
1957   gcc::jit::recording::context *ctxt = block->get_context ();
1958   JIT_LOG_FUNC (ctxt->get_logger ());
1959   /* LOC can be NULL.  */
1960   RETURN_IF_FAIL (lvalue, ctxt, loc, "NULL lvalue");
1961   RETURN_IF_FAIL (rvalue, ctxt, loc, "NULL rvalue");
1962   RETURN_IF_FAIL_PRINTF4 (
1963     compatible_types (lvalue->get_type (),
1964 		      rvalue->get_type ()),
1965     ctxt, loc,
1966     "mismatching types:"
1967     " assignment to %s (type: %s) from %s (type: %s)",
1968     lvalue->get_debug_string (),
1969     lvalue->get_type ()->get_debug_string (),
1970     rvalue->get_debug_string (),
1971     rvalue->get_type ()->get_debug_string ());
1972 
1973   gcc::jit::recording::statement *stmt = block->add_assignment (loc, lvalue, rvalue);
1974 
1975   /* "stmt" should be good enough to be usable in error-messages,
1976      but might still not be compilable; perform some more
1977      error-checking here.  We do this here so that the error messages
1978      can contain a stringified version of "stmt", whilst appearing
1979      as close as possible to the point of failure.  */
1980   lvalue->verify_valid_within_stmt (__func__, stmt);
1981   rvalue->verify_valid_within_stmt (__func__, stmt);
1982 }
1983 
1984 /* Public entrypoint.  See description in libgccjit.h.
1985 
1986    After error-checking, the real work is done by the
1987    gcc::jit::recording::block::add_assignment_op method in
1988    jit-recording.c.  */
1989 
1990 void
gcc_jit_block_add_assignment_op(gcc_jit_block * block,gcc_jit_location * loc,gcc_jit_lvalue * lvalue,enum gcc_jit_binary_op op,gcc_jit_rvalue * rvalue)1991 gcc_jit_block_add_assignment_op (gcc_jit_block *block,
1992 				 gcc_jit_location *loc,
1993 				 gcc_jit_lvalue *lvalue,
1994 				 enum gcc_jit_binary_op op,
1995 				 gcc_jit_rvalue *rvalue)
1996 {
1997   RETURN_IF_NOT_VALID_BLOCK (block, loc);
1998   gcc::jit::recording::context *ctxt = block->get_context ();
1999   JIT_LOG_FUNC (ctxt->get_logger ());
2000   /* LOC can be NULL.  */
2001   RETURN_IF_FAIL (lvalue, ctxt, loc, "NULL lvalue");
2002   RETURN_IF_FAIL_PRINTF1 (
2003     valid_binary_op_p (op),
2004     ctxt, loc,
2005     "unrecognized value for enum gcc_jit_binary_op: %i",
2006     op);
2007   RETURN_IF_FAIL (rvalue, ctxt, loc, "NULL rvalue");
2008   RETURN_IF_FAIL_PRINTF4 (
2009     compatible_types (lvalue->get_type (),
2010 		      rvalue->get_type ()),
2011     ctxt, loc,
2012     "mismatching types:"
2013     " assignment to %s (type: %s) involving %s (type: %s)",
2014     lvalue->get_debug_string (),
2015     lvalue->get_type ()->get_debug_string (),
2016     rvalue->get_debug_string (),
2017     rvalue->get_type ()->get_debug_string ());
2018 
2019   gcc::jit::recording::statement *stmt = block->add_assignment_op (loc, lvalue, op, rvalue);
2020 
2021   /* "stmt" should be good enough to be usable in error-messages,
2022      but might still not be compilable; perform some more
2023      error-checking here.  We do this here so that the error messages
2024      can contain a stringified version of "stmt", whilst appearing
2025      as close as possible to the point of failure.  */
2026   lvalue->verify_valid_within_stmt (__func__, stmt);
2027   rvalue->verify_valid_within_stmt (__func__, stmt);
2028 }
2029 
2030 /* Internal helper function for determining if rvalue BOOLVAL is of
2031    boolean type.  For use by gcc_jit_block_end_with_conditional.  */
2032 
2033 static bool
is_bool(gcc_jit_rvalue * boolval)2034 is_bool (gcc_jit_rvalue *boolval)
2035 {
2036   gcc::jit::recording::type *actual_type = boolval->get_type ();
2037   gcc::jit::recording::type *bool_type =
2038     boolval->m_ctxt->get_type (GCC_JIT_TYPE_BOOL);
2039   return actual_type == bool_type;
2040 }
2041 
2042 /* Public entrypoint.  See description in libgccjit.h.
2043 
2044    After error-checking, the real work is done by the
2045    gcc::jit::recording::block::end_with_conditional method in
2046    jit-recording.c.  */
2047 
2048 void
gcc_jit_block_end_with_conditional(gcc_jit_block * block,gcc_jit_location * loc,gcc_jit_rvalue * boolval,gcc_jit_block * on_true,gcc_jit_block * on_false)2049 gcc_jit_block_end_with_conditional (gcc_jit_block *block,
2050 				    gcc_jit_location *loc,
2051 				    gcc_jit_rvalue *boolval,
2052 				    gcc_jit_block *on_true,
2053 				    gcc_jit_block *on_false)
2054 {
2055   RETURN_IF_NOT_VALID_BLOCK (block, loc);
2056   gcc::jit::recording::context *ctxt = block->get_context ();
2057   JIT_LOG_FUNC (ctxt->get_logger ());
2058   /* LOC can be NULL.  */
2059   RETURN_IF_FAIL (boolval, ctxt, loc, "NULL boolval");
2060   RETURN_IF_FAIL_PRINTF2 (
2061    is_bool (boolval), ctxt, loc,
2062    "%s (type: %s) is not of boolean type ",
2063    boolval->get_debug_string (),
2064    boolval->get_type ()->get_debug_string ());
2065   RETURN_IF_FAIL (on_true, ctxt, loc, "NULL on_true");
2066   RETURN_IF_FAIL (on_true, ctxt, loc, "NULL on_false");
2067   RETURN_IF_FAIL_PRINTF4 (
2068     block->get_function () == on_true->get_function (),
2069     ctxt, loc,
2070     "\"on_true\" block is not in same function:"
2071     " source block %s is in function %s"
2072     " whereas target block %s is in function %s",
2073     block->get_debug_string (),
2074     block->get_function ()->get_debug_string (),
2075     on_true->get_debug_string (),
2076     on_true->get_function ()->get_debug_string ());
2077   RETURN_IF_FAIL_PRINTF4 (
2078     block->get_function () == on_false->get_function (),
2079     ctxt, loc,
2080     "\"on_false\" block is not in same function:"
2081     " source block %s is in function %s"
2082     " whereas target block %s is in function %s",
2083     block->get_debug_string (),
2084     block->get_function ()->get_debug_string (),
2085     on_false->get_debug_string (),
2086     on_false->get_function ()->get_debug_string ());
2087 
2088   gcc::jit::recording::statement *stmt = block->end_with_conditional (loc, boolval, on_true, on_false);
2089 
2090   /* "stmt" should be good enough to be usable in error-messages,
2091      but might still not be compilable; perform some more
2092      error-checking here.  We do this here so that the error messages
2093      can contain a stringified version of "stmt", whilst appearing
2094      as close as possible to the point of failure.  */
2095   boolval->verify_valid_within_stmt (__func__, stmt);
2096 }
2097 
2098 /* Public entrypoint.  See description in libgccjit.h.
2099 
2100    After error-checking, the real work is done by the
2101    gcc::jit::recording::block::add_comment method in
2102    jit-recording.c.  */
2103 
2104 void
gcc_jit_block_add_comment(gcc_jit_block * block,gcc_jit_location * loc,const char * text)2105 gcc_jit_block_add_comment (gcc_jit_block *block,
2106 			   gcc_jit_location *loc,
2107 			   const char *text)
2108 {
2109   RETURN_IF_NOT_VALID_BLOCK (block, loc);
2110   gcc::jit::recording::context *ctxt = block->get_context ();
2111   JIT_LOG_FUNC (ctxt->get_logger ());
2112   /* LOC can be NULL.  */
2113   RETURN_IF_FAIL (text, ctxt, loc, "NULL text");
2114 
2115   block->add_comment (loc, text);
2116 }
2117 
2118 /* Public entrypoint.  See description in libgccjit.h.
2119 
2120    After error-checking, the real work is done by the
2121    gcc::jit::recording::block::end_with_jump method in
2122    jit-recording.c.  */
2123 
2124 void
gcc_jit_block_end_with_jump(gcc_jit_block * block,gcc_jit_location * loc,gcc_jit_block * target)2125 gcc_jit_block_end_with_jump (gcc_jit_block *block,
2126 			     gcc_jit_location *loc,
2127 			     gcc_jit_block *target)
2128 {
2129   RETURN_IF_NOT_VALID_BLOCK (block, loc);
2130   gcc::jit::recording::context *ctxt = block->get_context ();
2131   JIT_LOG_FUNC (ctxt->get_logger ());
2132   /* LOC can be NULL.  */
2133   RETURN_IF_FAIL (target, ctxt, loc, "NULL target");
2134   RETURN_IF_FAIL_PRINTF4 (
2135     block->get_function () == target->get_function (),
2136     ctxt, loc,
2137     "target block is not in same function:"
2138     " source block %s is in function %s"
2139     " whereas target block %s is in function %s",
2140     block->get_debug_string (),
2141     block->get_function ()->get_debug_string (),
2142     target->get_debug_string (),
2143     target->get_function ()->get_debug_string ());
2144 
2145   block->end_with_jump (loc, target);
2146 }
2147 
2148 /* Public entrypoint.  See description in libgccjit.h.
2149 
2150    After error-checking, the real work is done by the
2151    gcc::jit::recording::block::end_with_return method in
2152    jit-recording.c.  */
2153 
2154 void
gcc_jit_block_end_with_return(gcc_jit_block * block,gcc_jit_location * loc,gcc_jit_rvalue * rvalue)2155 gcc_jit_block_end_with_return (gcc_jit_block *block,
2156 			       gcc_jit_location *loc,
2157 			       gcc_jit_rvalue *rvalue)
2158 {
2159   RETURN_IF_NOT_VALID_BLOCK (block, loc);
2160   gcc::jit::recording::context *ctxt = block->get_context ();
2161   JIT_LOG_FUNC (ctxt->get_logger ());
2162   /* LOC can be NULL.  */
2163   gcc::jit::recording::function *func = block->get_function ();
2164   RETURN_IF_FAIL (rvalue, ctxt, loc, "NULL rvalue");
2165   RETURN_IF_FAIL_PRINTF4 (
2166     compatible_types (
2167       func->get_return_type (),
2168       rvalue->get_type ()),
2169     ctxt, loc,
2170     "mismatching types:"
2171     " return of %s (type: %s) in function %s (return type: %s)",
2172     rvalue->get_debug_string (),
2173     rvalue->get_type ()->get_debug_string (),
2174     func->get_debug_string (),
2175     func->get_return_type ()->get_debug_string ());
2176 
2177   gcc::jit::recording::statement *stmt = block->end_with_return (loc, rvalue);
2178 
2179   /* "stmt" should be good enough to be usable in error-messages,
2180      but might still not be compilable; perform some more
2181      error-checking here.  We do this here so that the error messages
2182      can contain a stringified version of "stmt", whilst appearing
2183      as close as possible to the point of failure.  */
2184   rvalue->verify_valid_within_stmt (__func__, stmt);
2185 }
2186 
2187 /* Public entrypoint.  See description in libgccjit.h.
2188 
2189    After error-checking, the real work is done by the
2190    gcc::jit::recording::block::end_with_return method in
2191    jit-recording.c.  */
2192 
2193 void
gcc_jit_block_end_with_void_return(gcc_jit_block * block,gcc_jit_location * loc)2194 gcc_jit_block_end_with_void_return (gcc_jit_block *block,
2195 				    gcc_jit_location *loc)
2196 {
2197   RETURN_IF_NOT_VALID_BLOCK (block, loc);
2198   gcc::jit::recording::context *ctxt = block->get_context ();
2199   JIT_LOG_FUNC (ctxt->get_logger ());
2200   /* LOC can be NULL.  */
2201   gcc::jit::recording::function *func = block->get_function ();
2202   RETURN_IF_FAIL_PRINTF2 (
2203     func->get_return_type () == ctxt->get_type (GCC_JIT_TYPE_VOID),
2204     ctxt, loc,
2205     "mismatching types:"
2206     " void return in function %s (return type: %s)",
2207     func->get_debug_string (),
2208     func->get_return_type ()->get_debug_string ());
2209 
2210   block->end_with_return (loc, NULL);
2211 }
2212 
2213 /* Public entrypoint.  See description in libgccjit.h.
2214 
2215    After error-checking, the real work is done by the
2216    gcc::jit::recording::context::new_case method in
2217    jit-recording.c.  */
2218 
2219 gcc_jit_case *
gcc_jit_context_new_case(gcc_jit_context * ctxt,gcc_jit_rvalue * min_value,gcc_jit_rvalue * max_value,gcc_jit_block * block)2220 gcc_jit_context_new_case (gcc_jit_context *ctxt,
2221 			  gcc_jit_rvalue *min_value,
2222 			  gcc_jit_rvalue *max_value,
2223 			  gcc_jit_block *block)
2224 {
2225   RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
2226   JIT_LOG_FUNC (ctxt->get_logger ());
2227   RETURN_NULL_IF_FAIL (min_value, ctxt, NULL, "NULL min_value");
2228   RETURN_NULL_IF_FAIL (max_value, ctxt, NULL, "NULL max_value");
2229   RETURN_NULL_IF_FAIL (block, ctxt, NULL, "NULL block");
2230 
2231   RETURN_NULL_IF_FAIL_PRINTF1 (min_value->is_constant (), ctxt, NULL,
2232 			       "min_value is not a constant: %s",
2233 			       min_value->get_debug_string ());
2234   RETURN_NULL_IF_FAIL_PRINTF1 (max_value->is_constant (), ctxt, NULL,
2235 			       "max_value is not a constant: %s",
2236 			       max_value->get_debug_string ());
2237   RETURN_NULL_IF_FAIL_PRINTF2 (
2238     min_value->get_type ()->is_int (),
2239     ctxt, NULL,
2240     "min_value: %s (type: %s) is not of integer type",
2241     min_value->get_debug_string (),
2242     min_value->get_type ()->get_debug_string ());
2243   RETURN_NULL_IF_FAIL_PRINTF2 (
2244     max_value->get_type ()->is_int (),
2245     ctxt, NULL,
2246     "max_value: %s (type: %s) is not of integer type",
2247     max_value->get_debug_string (),
2248     max_value->get_type ()->get_debug_string ());
2249 
2250   wide_int wi_min, wi_max;
2251   if (!min_value->get_wide_int (&wi_min))
2252     gcc_unreachable ();
2253   if (!max_value->get_wide_int (&wi_max))
2254     gcc_unreachable ();
2255   RETURN_NULL_IF_FAIL_PRINTF2 (
2256     wi::les_p (wi_min, wi_max),
2257     ctxt, NULL,
2258     "min_value: %s > max_value: %s",
2259     min_value->get_debug_string (),
2260     max_value->get_debug_string ());
2261   return (gcc_jit_case *)ctxt->new_case (min_value,
2262 					 max_value,
2263 					 block);
2264 }
2265 
2266 /* Public entrypoint.  See description in libgccjit.h.
2267 
2268    After error-checking, this calls the trivial
2269    gcc::jit::recording::memento::as_object method (a case is a
2270    memento), in jit-recording.h.  */
2271 
2272 gcc_jit_object *
gcc_jit_case_as_object(gcc_jit_case * case_)2273 gcc_jit_case_as_object (gcc_jit_case *case_)
2274 {
2275   RETURN_NULL_IF_FAIL (case_, NULL, NULL, "NULL case");
2276 
2277   return static_cast <gcc_jit_object *> (case_->as_object ());
2278 }
2279 
2280 /* Helper function for gcc_jit_block_end_with_switch and
2281    valid_case_for_switch.  */
2282 
2283 static bool
valid_dest_for_switch(gcc::jit::recording::context * ctxt,gcc_jit_location * loc,const char * api_funcname,gcc::jit::recording::block * switch_block,gcc::jit::recording::block * dest_block,const char * dest_block_desc)2284 valid_dest_for_switch (gcc::jit::recording::context *ctxt,
2285 		       gcc_jit_location *loc,
2286 		       const char *api_funcname,
2287 		       gcc::jit::recording::block *switch_block,
2288 		       gcc::jit::recording::block *dest_block,
2289 		       const char *dest_block_desc)
2290 {
2291   if (!dest_block)
2292     {
2293       jit_error (ctxt, loc, "%s: NULL %s", api_funcname, dest_block_desc);
2294       return false;
2295     }
2296   gcc::jit::recording::function *switch_fn = switch_block->get_function ();
2297   gcc::jit::recording::function *dest_fn = dest_block->get_function ();
2298   if (switch_fn != dest_fn)
2299     {
2300       jit_error (ctxt, loc,
2301 		 "%s: %s is not in same function:"
2302 		 " switch block %s is in function %s"
2303 		 " whereas %s %s is in function %s",
2304 		 api_funcname,
2305 		 dest_block_desc,
2306 		 switch_block->get_debug_string (),
2307 		 switch_fn->get_debug_string (),
2308 		 dest_block_desc,
2309 		 dest_block->get_debug_string (),
2310 		 dest_fn->get_debug_string ());
2311       return false;
2312     }
2313   return true;
2314 }
2315 
2316 /* Helper function for gcc_jit_block_end_with_switch.  */
2317 
2318 static bool
valid_case_for_switch(gcc::jit::recording::context * ctxt,gcc_jit_location * loc,const char * api_funcname,gcc_jit_block * switch_block,gcc_jit_rvalue * expr,gcc_jit_case * case_,const char * case_desc,int case_idx)2319 valid_case_for_switch (gcc::jit::recording::context *ctxt,
2320 		       gcc_jit_location *loc,
2321 		       const char *api_funcname,
2322 		       gcc_jit_block *switch_block,
2323 		       gcc_jit_rvalue *expr,
2324 		       gcc_jit_case *case_,
2325 		       const char *case_desc,
2326 		       int case_idx)
2327 {
2328   if (!case_)
2329     {
2330       jit_error (ctxt, loc,
2331 		 "%s:"
2332 		 " NULL case %i",
2333 		 api_funcname,
2334 		 case_idx);
2335       return false;
2336     }
2337   if (!valid_dest_for_switch (ctxt, loc,
2338 			      api_funcname,
2339 			      switch_block,
2340 			      case_->get_dest_block (),
2341 			      case_desc))
2342     return false;
2343   gcc::jit::recording::type *expr_type = expr->get_type ();
2344   if (expr_type != case_->get_min_value ()->get_type ())
2345     {
2346       jit_error (ctxt, loc,
2347 		 "%s:"
2348 		 " mismatching types between case and expression:"
2349 		 " cases[%i]->min_value: %s (type: %s)"
2350 		 " expr: %s (type: %s)",
2351 		 api_funcname,
2352 		 case_idx,
2353 		 case_->get_min_value ()->get_debug_string (),
2354 		 case_->get_min_value ()->get_type ()->get_debug_string (),
2355 		 expr->get_debug_string (),
2356 		 expr_type->get_debug_string ());
2357       return false;
2358     }
2359   if (expr_type != case_->get_max_value ()->get_type ())
2360     {
2361       jit_error (ctxt, loc,
2362 		 "%s:"
2363 		 " mismatching types between case and expression:"
2364 		 " cases[%i]->max_value: %s (type: %s)"
2365 		 " expr: %s (type: %s)",
2366 		 api_funcname,
2367 		 case_idx,
2368 		 case_->get_max_value ()->get_debug_string (),
2369 		 case_->get_max_value ()->get_type ()->get_debug_string (),
2370 		 expr->get_debug_string (),
2371 		 expr_type->get_debug_string ());
2372       return false;
2373     }
2374   return true;
2375 }
2376 
2377 /* A class for holding the data we need to perform error-checking
2378    on a libgccjit API call.  */
2379 
2380 class api_call_validator
2381 {
2382  public:
api_call_validator(gcc::jit::recording::context * ctxt,gcc_jit_location * loc,const char * funcname)2383   api_call_validator (gcc::jit::recording::context *ctxt,
2384 		      gcc_jit_location *loc,
2385 		      const char *funcname)
2386   : m_ctxt (ctxt),
2387     m_loc (loc),
2388     m_funcname (funcname)
2389   {}
2390 
2391  protected:
2392   gcc::jit::recording::context *m_ctxt;
2393   gcc_jit_location *m_loc;
2394   const char *m_funcname;
2395 };
2396 
2397 /* A class for verifying that the ranges of cases within
2398    gcc_jit_block_end_with_switch don't overlap.  */
2399 
2400 class case_range_validator : public api_call_validator
2401 {
2402  public:
2403   case_range_validator (gcc::jit::recording::context *ctxt,
2404 			gcc_jit_location *loc,
2405 			const char *funcname);
2406 
2407   bool
2408   validate (gcc_jit_case *case_, int idx);
2409 
2410  private:
2411   static int
2412   case_compare (gcc::jit::recording::rvalue *k1,
2413 		gcc::jit::recording::rvalue *k2);
2414 
2415   static wide_int
2416   get_wide_int (gcc::jit::recording::rvalue *k);
2417 
2418  private:
2419   typed_splay_tree <gcc::jit::recording::rvalue *, gcc_jit_case *> m_cases;
2420 };
2421 
2422 /* case_range_validator's ctor.  */
2423 
case_range_validator(gcc::jit::recording::context * ctxt,gcc_jit_location * loc,const char * funcname)2424 case_range_validator::case_range_validator (gcc::jit::recording::context *ctxt,
2425 					    gcc_jit_location *loc,
2426 					    const char *funcname)
2427 : api_call_validator (ctxt, loc, funcname),
2428   m_cases (case_compare, NULL, NULL)
2429 {
2430 }
2431 
2432 /* Ensure that the range of CASE_ does not overlap with any of the
2433    ranges of cases we've already seen.
2434    Return true if everything is OK.
2435    Return false and emit an error if there is an overlap.
2436    Compare with c-family/c-common.c:c_add_case_label.  */
2437 
2438 bool
validate(gcc_jit_case * case_,int case_idx)2439 case_range_validator::validate (gcc_jit_case *case_,
2440 				int case_idx)
2441 {
2442   /* Look up the LOW_VALUE in the table of case labels we already
2443      have.  */
2444   gcc_jit_case *other = m_cases.lookup (case_->get_min_value ());
2445 
2446   /* If there was not an exact match, check for overlapping ranges.  */
2447   if (!other)
2448     {
2449       gcc_jit_case *pred;
2450       gcc_jit_case *succ;
2451 
2452       /* Even though there wasn't an exact match, there might be an
2453 	 overlap between this case range and another case range.
2454 	 Since we've (inductively) not allowed any overlapping case
2455 	 ranges, we simply need to find the greatest low case label
2456 	 that is smaller that CASE_MIN_VALUE, and the smallest low case
2457 	 label that is greater than CASE_MAX_VALUE.  If there is an overlap
2458 	 it will occur in one of these two ranges.  */
2459       pred = m_cases.predecessor (case_->get_min_value ());
2460       succ = m_cases.successor (case_->get_max_value ());
2461 
2462       /* Check to see if the PRED overlaps.  It is smaller than
2463 	 the LOW_VALUE, so we only need to check its max value.  */
2464       if (pred)
2465 	{
2466 	  wide_int wi_case_min = get_wide_int (case_->get_min_value ());
2467 	  wide_int wi_pred_max = get_wide_int (pred->get_max_value ());
2468 	  if (wi::ges_p (wi_pred_max, wi_case_min))
2469 	    other = pred;
2470 	}
2471 
2472       if (!other && succ)
2473 	{
2474 	  /* Check to see if the SUCC overlaps.  The low end of that
2475 	     range is bigger than the low end of the current range.  */
2476 	  wide_int wi_case_max = get_wide_int (case_->get_max_value ());
2477 	  wide_int wi_succ_min = get_wide_int (succ->get_min_value ());
2478 	  if (wi::les_p (wi_succ_min, wi_case_max))
2479 	    other = succ;
2480 	}
2481     }
2482 
2483   /* If there was an overlap, issue an error.  */
2484   if (other)
2485     {
2486       jit_error (m_ctxt, m_loc,
2487 		 "%s: duplicate (or overlapping) cases values:"
2488 		 " case %i: %s overlaps %s",
2489 		 m_funcname,
2490 		 case_idx,
2491 		 case_->get_debug_string (),
2492 		 other->get_debug_string ());
2493       return false;
2494     }
2495 
2496   /* Register this case label in the splay tree.  */
2497   m_cases.insert (case_->get_min_value (),
2498 		  case_);
2499   return true;
2500 }
2501 
2502 /* Compare with c-family/c-common.c:case_compare, which acts on tree
2503    nodes, rather than rvalue *.
2504 
2505    Comparator for case label values.  K1 and K2 must be constant integer
2506    values (anything else should have been rejected by
2507    gcc_jit_context_new_case.
2508 
2509    Returns -1 if K1 is ordered before K2, -1 if K1 is ordered after
2510    K2, and 0 if K1 and K2 are equal.  */
2511 
2512 int
case_compare(gcc::jit::recording::rvalue * k1,gcc::jit::recording::rvalue * k2)2513 case_range_validator::case_compare (gcc::jit::recording::rvalue * k1,
2514 				    gcc::jit::recording::rvalue * k2)
2515 {
2516   wide_int wi1 = get_wide_int (k1);
2517   wide_int wi2 = get_wide_int (k2);
2518   return wi::cmps(wi1, wi2);
2519 }
2520 
2521 /* Given a const int rvalue K, get the underlying value as a wide_int.  */
2522 
2523 wide_int
get_wide_int(gcc::jit::recording::rvalue * k)2524 case_range_validator::get_wide_int (gcc::jit::recording::rvalue *k)
2525 {
2526   wide_int wi;
2527   bool got_wi = k->get_wide_int (&wi);
2528   gcc_assert (got_wi);
2529   return wi;
2530 }
2531 
2532 /* Public entrypoint.  See description in libgccjit.h.
2533 
2534    After error-checking, the real work is done by the
2535    gcc::jit::recording::block::end_with_switch method in
2536    jit-recording.c.  */
2537 
2538 void
gcc_jit_block_end_with_switch(gcc_jit_block * block,gcc_jit_location * loc,gcc_jit_rvalue * expr,gcc_jit_block * default_block,int num_cases,gcc_jit_case ** cases)2539 gcc_jit_block_end_with_switch (gcc_jit_block *block,
2540 			       gcc_jit_location *loc,
2541 			       gcc_jit_rvalue *expr,
2542 			       gcc_jit_block *default_block,
2543 			       int num_cases,
2544 			       gcc_jit_case **cases)
2545 {
2546   RETURN_IF_NOT_VALID_BLOCK (block, loc);
2547   gcc::jit::recording::context *ctxt = block->get_context ();
2548   JIT_LOG_FUNC (ctxt->get_logger ());
2549   /* LOC can be NULL.  */
2550   RETURN_IF_FAIL (expr, ctxt, loc,
2551 		  "NULL expr");
2552   gcc::jit::recording::type *expr_type = expr->get_type ();
2553   RETURN_IF_FAIL_PRINTF2 (
2554     expr_type->is_int (),
2555     ctxt, loc,
2556     "expr: %s (type: %s) is not of integer type",
2557     expr->get_debug_string (),
2558     expr_type->get_debug_string ());
2559   if (!valid_dest_for_switch (ctxt, loc,
2560 			      __func__,
2561 			      block,
2562 			      default_block,
2563 			      "default_block"))
2564     return;
2565   RETURN_IF_FAIL (num_cases >= 0, ctxt, loc, "num_cases < 0");
2566   case_range_validator crv (ctxt, loc, __func__);
2567   for (int i = 0; i < num_cases; i++)
2568     {
2569       char case_desc[32];
2570       snprintf (case_desc, sizeof (case_desc),
2571 		"cases[%i]", i);
2572       if (!valid_case_for_switch (ctxt, loc,
2573 				  __func__,
2574 				  block,
2575 				  expr,
2576 				  cases[i],
2577 				  case_desc,
2578 				  i))
2579 	return;
2580       if (!crv.validate (cases[i], i))
2581 	return;
2582     }
2583 
2584   block->end_with_switch (loc, expr, default_block,
2585 			  num_cases,
2586 			  (gcc::jit::recording::case_ **)cases);
2587 }
2588 
2589 /**********************************************************************
2590  Option-management
2591  **********************************************************************/
2592 
2593 /* Public entrypoint.  See description in libgccjit.h.
2594 
2595    After error-checking, the real work is done by the
2596    gcc::jit::recording::context::set_str_option method in
2597    jit-recording.c.  */
2598 
2599 void
gcc_jit_context_set_str_option(gcc_jit_context * ctxt,enum gcc_jit_str_option opt,const char * value)2600 gcc_jit_context_set_str_option (gcc_jit_context *ctxt,
2601 				enum gcc_jit_str_option opt,
2602 				const char *value)
2603 {
2604   RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
2605   JIT_LOG_FUNC (ctxt->get_logger ());
2606   /* opt is checked by the inner function.
2607      value can be NULL.  */
2608 
2609   ctxt->set_str_option (opt, value);
2610 }
2611 
2612 /* Public entrypoint.  See description in libgccjit.h.
2613 
2614    After error-checking, the real work is done by the
2615    gcc::jit::recording::context::set_int_option method in
2616    jit-recording.c.  */
2617 
2618 void
gcc_jit_context_set_int_option(gcc_jit_context * ctxt,enum gcc_jit_int_option opt,int value)2619 gcc_jit_context_set_int_option (gcc_jit_context *ctxt,
2620 				enum gcc_jit_int_option opt,
2621 				int value)
2622 {
2623   RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
2624   JIT_LOG_FUNC (ctxt->get_logger ());
2625   /* opt is checked by the inner function.  */
2626 
2627   ctxt->set_int_option (opt, value);
2628 }
2629 
2630 /* Public entrypoint.  See description in libgccjit.h.
2631 
2632    After error-checking, the real work is done by the
2633    gcc::jit::recording::context::set_bool_option method in
2634    jit-recording.c.  */
2635 
2636 void
gcc_jit_context_set_bool_option(gcc_jit_context * ctxt,enum gcc_jit_bool_option opt,int value)2637 gcc_jit_context_set_bool_option (gcc_jit_context *ctxt,
2638 				 enum gcc_jit_bool_option opt,
2639 				 int value)
2640 {
2641   RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
2642   JIT_LOG_FUNC (ctxt->get_logger ());
2643   /* opt is checked by the inner function.  */
2644 
2645   ctxt->set_bool_option (opt, value);
2646 }
2647 
2648 /* Public entrypoint.  See description in libgccjit.h.
2649 
2650    After error-checking, the real work is done by the
2651    gcc::jit::recording::context::set_inner_bool_option method in
2652    jit-recording.c.  */
2653 
2654 void
gcc_jit_context_set_bool_allow_unreachable_blocks(gcc_jit_context * ctxt,int bool_value)2655 gcc_jit_context_set_bool_allow_unreachable_blocks (gcc_jit_context *ctxt,
2656 						   int bool_value)
2657 {
2658   RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
2659   JIT_LOG_FUNC (ctxt->get_logger ());
2660   ctxt->set_inner_bool_option (
2661     gcc::jit::INNER_BOOL_OPTION_ALLOW_UNREACHABLE_BLOCKS,
2662     bool_value);
2663 }
2664 
2665 /* Public entrypoint.  See description in libgccjit.h.
2666 
2667    After error-checking, the real work is done by the
2668    gcc::jit::recording::context::set_inner_bool_option method in
2669    jit-recording.c.  */
2670 
2671 extern void
gcc_jit_context_set_bool_use_external_driver(gcc_jit_context * ctxt,int bool_value)2672 gcc_jit_context_set_bool_use_external_driver (gcc_jit_context *ctxt,
2673 					      int bool_value)
2674 {
2675   RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
2676   JIT_LOG_FUNC (ctxt->get_logger ());
2677   ctxt->set_inner_bool_option (
2678     gcc::jit::INNER_BOOL_OPTION_USE_EXTERNAL_DRIVER,
2679     bool_value);
2680 }
2681 
2682 /* Public entrypoint.  See description in libgccjit.h.
2683 
2684    After error-checking, the real work is done by the
2685    gcc::jit::recording::context::add_command_line_option method in
2686    jit-recording.c.  */
2687 
2688 void
gcc_jit_context_add_command_line_option(gcc_jit_context * ctxt,const char * optname)2689 gcc_jit_context_add_command_line_option (gcc_jit_context *ctxt,
2690 					 const char *optname)
2691 {
2692   RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
2693   JIT_LOG_FUNC (ctxt->get_logger ());
2694   RETURN_IF_FAIL (optname, ctxt, NULL, "NULL optname");
2695   if (ctxt->get_logger ())
2696     ctxt->get_logger ()->log ("optname: %s", optname);
2697 
2698   ctxt->add_command_line_option (optname);
2699 }
2700 
2701 /* Public entrypoint.  See description in libgccjit.h.
2702 
2703    The real work is done by the
2704    gcc::jit::recording::context::add_driver_option method in
2705    jit-recording.c.  */
2706 
2707 void
gcc_jit_context_add_driver_option(gcc_jit_context * ctxt,const char * optname)2708 gcc_jit_context_add_driver_option (gcc_jit_context *ctxt,
2709 				   const char *optname)
2710 {
2711   RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
2712   JIT_LOG_FUNC (ctxt->get_logger ());
2713   RETURN_IF_FAIL (optname, ctxt, NULL, "NULL optname");
2714   if (ctxt->get_logger ())
2715     ctxt->get_logger ()->log ("optname: %s", optname);
2716 
2717   ctxt->add_driver_option (optname);
2718 }
2719 
2720 /* Public entrypoint.  See description in libgccjit.h.
2721 
2722    After error-checking, the real work is done by the
2723    gcc::jit::recording::context::enable_dump method in
2724    jit-recording.c.  */
2725 
2726 void
gcc_jit_context_enable_dump(gcc_jit_context * ctxt,const char * dumpname,char ** out_ptr)2727 gcc_jit_context_enable_dump (gcc_jit_context *ctxt,
2728 			     const char *dumpname,
2729 			     char **out_ptr)
2730 {
2731   RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
2732   JIT_LOG_FUNC (ctxt->get_logger ());
2733   RETURN_IF_FAIL (dumpname, ctxt, NULL, "NULL dumpname");
2734   RETURN_IF_FAIL (out_ptr, ctxt, NULL, "NULL out_ptr");
2735 
2736   ctxt->enable_dump (dumpname, out_ptr);
2737 }
2738 
2739 /* Public entrypoint.  See description in libgccjit.h.
2740 
2741    After error-checking, the real work is done by the
2742    gcc::jit::recording::context::compile method in
2743    jit-recording.c.  */
2744 
2745 gcc_jit_result *
gcc_jit_context_compile(gcc_jit_context * ctxt)2746 gcc_jit_context_compile (gcc_jit_context *ctxt)
2747 {
2748   RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
2749 
2750   JIT_LOG_FUNC (ctxt->get_logger ());
2751 
2752   ctxt->log ("in-memory compile of ctxt: %p", (void *)ctxt);
2753 
2754   gcc_jit_result *result = (gcc_jit_result *)ctxt->compile ();
2755 
2756   ctxt->log ("%s: returning (gcc_jit_result *)%p",
2757 	     __func__, (void *)result);
2758 
2759   return result;
2760 }
2761 
2762 /* Public entrypoint.  See description in libgccjit.h.
2763 
2764    After error-checking, the real work is done by the
2765    gcc::jit::recording::context::compile_to_file method in
2766    jit-recording.c.  */
2767 
2768 void
gcc_jit_context_compile_to_file(gcc_jit_context * ctxt,enum gcc_jit_output_kind output_kind,const char * output_path)2769 gcc_jit_context_compile_to_file (gcc_jit_context *ctxt,
2770 				 enum gcc_jit_output_kind output_kind,
2771 				 const char *output_path)
2772 {
2773   RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
2774   JIT_LOG_FUNC (ctxt->get_logger ());
2775   RETURN_IF_FAIL_PRINTF1 (
2776     ((output_kind >= GCC_JIT_OUTPUT_KIND_ASSEMBLER)
2777      && (output_kind <= GCC_JIT_OUTPUT_KIND_EXECUTABLE)),
2778     ctxt, NULL,
2779     "unrecognized output_kind: %i",
2780     output_kind);
2781   RETURN_IF_FAIL (output_path, ctxt, NULL, "NULL output_path");
2782 
2783   ctxt->log ("compile_to_file of ctxt: %p", (void *)ctxt);
2784   ctxt->log ("output_kind: %i", output_kind);
2785   ctxt->log ("output_path: %s", output_path);
2786 
2787   ctxt->compile_to_file (output_kind, output_path);
2788 }
2789 
2790 
2791 /* Public entrypoint.  See description in libgccjit.h.
2792 
2793    After error-checking, the real work is done by the
2794    gcc::jit::recording::context::dump_to_file method in
2795    jit-recording.c.  */
2796 
2797 void
gcc_jit_context_dump_to_file(gcc_jit_context * ctxt,const char * path,int update_locations)2798 gcc_jit_context_dump_to_file (gcc_jit_context *ctxt,
2799 			      const char *path,
2800 			      int update_locations)
2801 {
2802   RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
2803   JIT_LOG_FUNC (ctxt->get_logger ());
2804   RETURN_IF_FAIL (path, ctxt, NULL, "NULL path");
2805   ctxt->dump_to_file (path, update_locations);
2806 }
2807 
2808 /* Public entrypoint.  See description in libgccjit.h.  */
2809 
2810 void
gcc_jit_context_set_logfile(gcc_jit_context * ctxt,FILE * logfile,int flags,int verbosity)2811 gcc_jit_context_set_logfile (gcc_jit_context *ctxt,
2812 			     FILE *logfile,
2813 			     int flags,
2814 			     int verbosity)
2815 {
2816   RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
2817   JIT_LOG_FUNC (ctxt->get_logger ());
2818   RETURN_IF_FAIL ((flags == 0), ctxt, NULL, "flags must be 0 for now");
2819   RETURN_IF_FAIL ((verbosity == 0), ctxt, NULL, "verbosity must be 0 for now");
2820 
2821   gcc::jit::logger *logger;
2822   if (logfile)
2823     logger = new gcc::jit::logger (logfile, flags, verbosity);
2824   else
2825     logger = NULL;
2826   ctxt->set_logger (logger);
2827 }
2828 
2829 /* Public entrypoint.  See description in libgccjit.h.
2830 
2831    After error-checking, the real work is done by the
2832    gcc::jit::recording::context::dump_reproducer_to_file method in
2833    jit-recording.c.  */
2834 
2835 void
gcc_jit_context_dump_reproducer_to_file(gcc_jit_context * ctxt,const char * path)2836 gcc_jit_context_dump_reproducer_to_file (gcc_jit_context *ctxt,
2837 					 const char *path)
2838 {
2839   RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
2840   JIT_LOG_FUNC (ctxt->get_logger ());
2841   RETURN_IF_FAIL (path, ctxt, NULL, "NULL path");
2842   ctxt->dump_reproducer_to_file (path);
2843 }
2844 
2845 /* Public entrypoint.  See description in libgccjit.h.
2846 
2847    After error-checking, the real work is done by the
2848    gcc::jit::recording::context::get_first_error method in
2849    jit-recording.c.  */
2850 
2851 const char *
gcc_jit_context_get_first_error(gcc_jit_context * ctxt)2852 gcc_jit_context_get_first_error (gcc_jit_context *ctxt)
2853 {
2854   RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
2855   JIT_LOG_FUNC (ctxt->get_logger ());
2856 
2857   return ctxt->get_first_error ();
2858 }
2859 
2860 /* Public entrypoint.  See description in libgccjit.h.
2861 
2862    After error-checking, the real work is done by the
2863    gcc::jit::recording::context::get_last_error method in
2864    jit-recording.c.  */
2865 
2866 const char *
gcc_jit_context_get_last_error(gcc_jit_context * ctxt)2867 gcc_jit_context_get_last_error (gcc_jit_context *ctxt)
2868 {
2869   RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
2870 
2871   return ctxt->get_last_error ();
2872 }
2873 
2874 /* Public entrypoint.  See description in libgccjit.h.
2875 
2876    After error-checking, the real work is done by the
2877    gcc::jit::result::get_code method in jit-result.c.  */
2878 
2879 void *
gcc_jit_result_get_code(gcc_jit_result * result,const char * fnname)2880 gcc_jit_result_get_code (gcc_jit_result *result,
2881 			 const char *fnname)
2882 {
2883   RETURN_NULL_IF_FAIL (result, NULL, NULL, "NULL result");
2884   JIT_LOG_FUNC (result->get_logger ());
2885   RETURN_NULL_IF_FAIL (fnname, NULL, NULL, "NULL fnname");
2886 
2887   result->log ("locating fnname: %s", fnname);
2888   void *code = result->get_code (fnname);
2889   result->log ("%s: returning (void *)%p", __func__, code);
2890 
2891   return code;
2892 }
2893 
2894 /* Public entrypoint.  See description in libgccjit.h.
2895 
2896    After error-checking, the real work is done by the
2897    gcc::jit::result::get_global method in jit-result.c.  */
2898 
2899 void *
gcc_jit_result_get_global(gcc_jit_result * result,const char * name)2900 gcc_jit_result_get_global (gcc_jit_result *result,
2901 			   const char *name)
2902 {
2903   RETURN_NULL_IF_FAIL (result, NULL, NULL, "NULL result");
2904   JIT_LOG_FUNC (result->get_logger ());
2905   RETURN_NULL_IF_FAIL (name, NULL, NULL, "NULL name");
2906 
2907   void *global = result->get_global (name);
2908   result->log ("%s: returning (void *)%p", __func__, global);
2909 
2910   return global;
2911 }
2912 
2913 /* Public entrypoint.  See description in libgccjit.h.
2914 
2915    After error-checking, this is essentially a wrapper around the
2916    destructor for gcc::jit::result in jit-result.c.  */
2917 
2918 void
gcc_jit_result_release(gcc_jit_result * result)2919 gcc_jit_result_release (gcc_jit_result *result)
2920 {
2921   RETURN_IF_FAIL (result, NULL, NULL, "NULL result");
2922   JIT_LOG_FUNC (result->get_logger ());
2923   result->log ("deleting result: %p", (void *)result);
2924   delete result;
2925 }
2926 
2927 /**********************************************************************
2928  Timing support.
2929  **********************************************************************/
2930 
2931 /* Create a gcc_jit_timer instance, and start timing.  */
2932 
2933 gcc_jit_timer *
gcc_jit_timer_new(void)2934 gcc_jit_timer_new (void)
2935 {
2936   gcc_jit_timer *timer = new gcc_jit_timer ();
2937   timer->start (TV_TOTAL);
2938   timer->push (TV_JIT_CLIENT_CODE);
2939   return timer;
2940 }
2941 
2942 /* Release a gcc_jit_timer instance.  */
2943 
2944 void
gcc_jit_timer_release(gcc_jit_timer * timer)2945 gcc_jit_timer_release (gcc_jit_timer *timer)
2946 {
2947   RETURN_IF_FAIL (timer, NULL, NULL, "NULL timer");
2948 
2949   delete timer;
2950 }
2951 
2952 /* Associate a gcc_jit_timer instance with a context.  */
2953 
2954 void
gcc_jit_context_set_timer(gcc_jit_context * ctxt,gcc_jit_timer * timer)2955 gcc_jit_context_set_timer (gcc_jit_context *ctxt,
2956 			   gcc_jit_timer *timer)
2957 {
2958   RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL ctxt");
2959   RETURN_IF_FAIL (timer, ctxt, NULL, "NULL timer");
2960 
2961   ctxt->set_timer (timer);
2962 }
2963 
2964 /* Get the timer associated with a context (if any).  */
2965 
2966 gcc_jit_timer *
gcc_jit_context_get_timer(gcc_jit_context * ctxt)2967 gcc_jit_context_get_timer (gcc_jit_context *ctxt)
2968 {
2969   RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL ctxt");
2970 
2971   return (gcc_jit_timer *)ctxt->get_timer ();
2972 }
2973 
2974 /* Push the given item onto the timing stack.  */
2975 
2976 void
gcc_jit_timer_push(gcc_jit_timer * timer,const char * item_name)2977 gcc_jit_timer_push (gcc_jit_timer *timer,
2978 		    const char *item_name)
2979 {
2980   RETURN_IF_FAIL (timer, NULL, NULL, "NULL timer");
2981   RETURN_IF_FAIL (item_name, NULL, NULL, "NULL item_name");
2982   timer->push_client_item (item_name);
2983 }
2984 
2985 /* Pop the top item from the timing stack.  */
2986 
2987 void
gcc_jit_timer_pop(gcc_jit_timer * timer,const char * item_name)2988 gcc_jit_timer_pop (gcc_jit_timer *timer,
2989 		   const char *item_name)
2990 {
2991   RETURN_IF_FAIL (timer, NULL, NULL, "NULL timer");
2992 
2993   if (item_name)
2994     {
2995       const char *top_item_name = timer->get_topmost_item_name ();
2996 
2997       RETURN_IF_FAIL_PRINTF1
2998 	(top_item_name, NULL, NULL,
2999 	 "pop of empty timing stack (attempting to pop: \"%s\")",
3000 	 item_name);
3001 
3002       RETURN_IF_FAIL_PRINTF2
3003 	(strcmp (item_name, top_item_name) == 0, NULL, NULL,
3004 	 "mismatching item_name:"
3005 	 " top of timing stack: \"%s\","
3006 	 " attempting to pop: \"%s\"",
3007 	 top_item_name,
3008 	 item_name);
3009     }
3010 
3011   timer->pop_client_item ();
3012 }
3013 
3014 /* Print timing information to the given stream about activity since
3015    the timer was started.  */
3016 
3017 void
gcc_jit_timer_print(gcc_jit_timer * timer,FILE * f_out)3018 gcc_jit_timer_print (gcc_jit_timer *timer,
3019 		     FILE *f_out)
3020 {
3021   RETURN_IF_FAIL (timer, NULL, NULL, "NULL timer");
3022   RETURN_IF_FAIL (f_out, NULL, NULL, "NULL f_out");
3023 
3024   timer->pop (TV_JIT_CLIENT_CODE);
3025   timer->stop (TV_TOTAL);
3026   timer->print (f_out);
3027   timer->start (TV_TOTAL);
3028   timer->push (TV_JIT_CLIENT_CODE);
3029 }
3030 
3031 /* Public entrypoint.  See description in libgccjit.h.
3032 
3033    After error-checking, the real work is effectively done by the
3034    gcc::jit::base_call::set_require_tail_call setter in jit-recording.h.  */
3035 
3036 void
gcc_jit_rvalue_set_bool_require_tail_call(gcc_jit_rvalue * rvalue,int require_tail_call)3037 gcc_jit_rvalue_set_bool_require_tail_call (gcc_jit_rvalue *rvalue,
3038 					   int require_tail_call)
3039 {
3040   RETURN_IF_FAIL (rvalue, NULL, NULL, "NULL call");
3041   JIT_LOG_FUNC (rvalue->get_context ()->get_logger ());
3042 
3043   /* Verify that it's a call.  */
3044   gcc::jit::recording::base_call *call = rvalue->dyn_cast_base_call ();
3045   RETURN_IF_FAIL_PRINTF1 (call, NULL, NULL, "not a call: %s",
3046 			  rvalue->get_debug_string ());
3047 
3048   call->set_require_tail_call (require_tail_call);
3049 }
3050 
3051 /* Public entrypoint.  See description in libgccjit.h.
3052 
3053    After error-checking, the real work is done by the
3054    gcc::jit::recording::type::get_aligned method, in
3055    jit-recording.c.  */
3056 
3057 gcc_jit_type *
gcc_jit_type_get_aligned(gcc_jit_type * type,size_t alignment_in_bytes)3058 gcc_jit_type_get_aligned (gcc_jit_type *type,
3059 			  size_t alignment_in_bytes)
3060 {
3061   RETURN_NULL_IF_FAIL (type, NULL, NULL, "NULL type");
3062 
3063   gcc::jit::recording::context *ctxt = type->m_ctxt;
3064 
3065   JIT_LOG_FUNC (ctxt->get_logger ());
3066 
3067   RETURN_NULL_IF_FAIL_PRINTF1
3068     (pow2_or_zerop (alignment_in_bytes), ctxt, NULL,
3069      "alignment not a power of two: %zi",
3070      alignment_in_bytes);
3071 
3072   return (gcc_jit_type *)type->get_aligned (alignment_in_bytes);
3073 }
3074 
3075 /* Public entrypoint.  See description in libgccjit.h.
3076 
3077    After error-checking, the real work is done by the
3078    gcc::jit::recording::type::get_vector method, in
3079    jit-recording.c.  */
3080 
3081 gcc_jit_type *
gcc_jit_type_get_vector(gcc_jit_type * type,size_t num_units)3082 gcc_jit_type_get_vector (gcc_jit_type *type, size_t num_units)
3083 {
3084   RETURN_NULL_IF_FAIL (type, NULL, NULL, "NULL type");
3085 
3086   gcc::jit::recording::context *ctxt = type->m_ctxt;
3087 
3088   JIT_LOG_FUNC (ctxt->get_logger ());
3089 
3090   RETURN_NULL_IF_FAIL_PRINTF1
3091     (type->is_int () || type->is_float (), ctxt, NULL,
3092      "type is not integral or floating point: %s",
3093      type->get_debug_string ());
3094 
3095   RETURN_NULL_IF_FAIL_PRINTF1
3096     (pow2_or_zerop (num_units), ctxt, NULL,
3097      "num_units not a power of two: %zi",
3098      num_units);
3099 
3100   return (gcc_jit_type *)type->get_vector (num_units);
3101 }
3102 
3103 /* Public entrypoint.  See description in libgccjit.h.
3104 
3105    After error-checking, the real work is done by the
3106    gcc::jit::recording::function::get_address method, in
3107    jit-recording.c.  */
3108 
3109 gcc_jit_rvalue *
gcc_jit_function_get_address(gcc_jit_function * fn,gcc_jit_location * loc)3110 gcc_jit_function_get_address (gcc_jit_function *fn,
3111 			      gcc_jit_location *loc)
3112 {
3113   RETURN_NULL_IF_FAIL (fn, NULL, NULL, "NULL function");
3114 
3115   gcc::jit::recording::context *ctxt = fn->m_ctxt;
3116 
3117   JIT_LOG_FUNC (ctxt->get_logger ());
3118   /* LOC can be NULL.  */
3119 
3120   return (gcc_jit_rvalue *)fn->get_address (loc);
3121 }
3122 
3123 /* Public entrypoint.  See description in libgccjit.h.
3124 
3125    After error-checking, the real work is done by the
3126    gcc::jit::recording::context::new_rvalue_from_vector method, in
3127    jit-recording.c.  */
3128 
3129 extern gcc_jit_rvalue *
gcc_jit_context_new_rvalue_from_vector(gcc_jit_context * ctxt,gcc_jit_location * loc,gcc_jit_type * vec_type,size_t num_elements,gcc_jit_rvalue ** elements)3130 gcc_jit_context_new_rvalue_from_vector (gcc_jit_context *ctxt,
3131 					gcc_jit_location *loc,
3132 					gcc_jit_type *vec_type,
3133 					size_t num_elements,
3134 					gcc_jit_rvalue **elements)
3135 {
3136   RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL ctxt");
3137   JIT_LOG_FUNC (ctxt->get_logger ());
3138 
3139   /* LOC can be NULL.  */
3140   RETURN_NULL_IF_FAIL (vec_type, ctxt, loc, "NULL vec_type");
3141 
3142   /* "vec_type" must be a vector type.  */
3143   gcc::jit::recording::vector_type *as_vec_type
3144     = vec_type->dyn_cast_vector_type ();
3145   RETURN_NULL_IF_FAIL_PRINTF1 (as_vec_type, ctxt, loc,
3146 			       "%s is not a vector type",
3147 			       vec_type->get_debug_string ());
3148 
3149   /* "num_elements" must match.  */
3150   RETURN_NULL_IF_FAIL_PRINTF1 (
3151     num_elements == as_vec_type->get_num_units (), ctxt, loc,
3152     "num_elements != %zi", as_vec_type->get_num_units ());
3153 
3154   /* "elements must be non-NULL.  */
3155   RETURN_NULL_IF_FAIL (elements, ctxt, loc, "NULL elements");
3156 
3157   /* Each of "elements" must be non-NULL and of the correct type.  */
3158   gcc::jit::recording::type *element_type
3159     = as_vec_type->get_element_type ();
3160   for (size_t i = 0; i < num_elements; i++)
3161     {
3162       RETURN_NULL_IF_FAIL_PRINTF1 (
3163 	elements[i], ctxt, loc, "NULL elements[%zi]", i);
3164       RETURN_NULL_IF_FAIL_PRINTF4 (
3165 	compatible_types (element_type,
3166 			  elements[i]->get_type ()),
3167 	ctxt, loc,
3168 	"mismatching type for element[%zi] (expected type: %s): %s (type: %s)",
3169 	i,
3170 	element_type->get_debug_string (),
3171 	elements[i]->get_debug_string (),
3172 	elements[i]->get_type ()->get_debug_string ());
3173     }
3174 
3175   return (gcc_jit_rvalue *)ctxt->new_rvalue_from_vector
3176     (loc,
3177      as_vec_type,
3178      (gcc::jit::recording::rvalue **)elements);
3179 }
3180 
3181 /* A mutex around the cached state in parse_basever.
3182    Ideally this would be within parse_basever, but the mutex is only needed
3183    by libgccjit.  */
3184 
3185 static pthread_mutex_t version_mutex = PTHREAD_MUTEX_INITIALIZER;
3186 
3187 struct version_info
3188 {
3189   /* Default constructor.  Populate via parse_basever,
3190      guarded by version_mutex.  */
version_infoversion_info3191   version_info ()
3192   {
3193     pthread_mutex_lock (&version_mutex);
3194     parse_basever (&major, &minor, &patchlevel);
3195     pthread_mutex_unlock (&version_mutex);
3196   }
3197 
3198   int major;
3199   int minor;
3200   int patchlevel;
3201 };
3202 
3203 
3204 extern int
gcc_jit_version_major(void)3205 gcc_jit_version_major (void)
3206 {
3207   version_info vi;
3208   return vi.major;
3209 }
3210 
3211 extern int
gcc_jit_version_minor(void)3212 gcc_jit_version_minor (void)
3213 {
3214   version_info vi;
3215   return vi.minor;
3216 }
3217 
3218 extern int
gcc_jit_version_patchlevel(void)3219 gcc_jit_version_patchlevel (void)
3220 {
3221   version_info vi;
3222   return vi.patchlevel;
3223 }
3224