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