Branch data Line data Source code
1 : : /* Implementation of the C API; all wrappers into the internal C++ API
2 : : Copyright (C) 2013-2024 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 : : #define INCLUDE_MUTEX
23 : : #include "system.h"
24 : : #include "coretypes.h"
25 : : #include "timevar.h"
26 : : #include "typed-splay-tree.h"
27 : : #include "cppbuiltin.h"
28 : :
29 : : #include "libgccjit.h"
30 : : #include "jit-recording.h"
31 : : #include "jit-result.h"
32 : :
33 : : /* The opaque types used by the public API are actually subclasses
34 : : of the gcc::jit::recording classes. */
35 : :
36 : 3426 : struct gcc_jit_context : public gcc::jit::recording::context
37 : : {
38 : 1715 : gcc_jit_context (gcc_jit_context *parent_ctxt) :
39 : 1715 : context (parent_ctxt)
40 : : {}
41 : : };
42 : :
43 : : struct gcc_jit_result : public gcc::jit::result
44 : : {
45 : : };
46 : :
47 : : struct gcc_jit_object : public gcc::jit::recording::memento
48 : : {
49 : : };
50 : :
51 : : struct gcc_jit_location : public gcc::jit::recording::location
52 : : {
53 : : };
54 : :
55 : : struct gcc_jit_type : public gcc::jit::recording::type
56 : : {
57 : : };
58 : :
59 : : struct gcc_jit_struct : public gcc::jit::recording::struct_
60 : : {
61 : : };
62 : :
63 : : struct gcc_jit_function_type : public gcc::jit::recording::function_type
64 : : {
65 : : };
66 : :
67 : : struct gcc_jit_vector_type : public gcc::jit::recording::vector_type
68 : : {
69 : : };
70 : :
71 : : struct gcc_jit_field : public gcc::jit::recording::field
72 : : {
73 : : };
74 : :
75 : : struct gcc_jit_bitfield : public gcc::jit::recording::bitfield
76 : : {
77 : : };
78 : :
79 : : struct gcc_jit_function : public gcc::jit::recording::function
80 : : {
81 : : };
82 : :
83 : : struct gcc_jit_block : public gcc::jit::recording::block
84 : : {
85 : : };
86 : :
87 : : struct gcc_jit_rvalue : public gcc::jit::recording::rvalue
88 : : {
89 : : };
90 : :
91 : : struct gcc_jit_lvalue : public gcc::jit::recording::lvalue
92 : : {
93 : : };
94 : :
95 : : struct gcc_jit_param : public gcc::jit::recording::param
96 : : {
97 : : };
98 : :
99 : : struct gcc_jit_case : public gcc::jit::recording::case_
100 : : {
101 : : };
102 : :
103 : 42 : struct gcc_jit_timer : public timer
104 : : {
105 : : };
106 : :
107 : : struct gcc_jit_extended_asm : public gcc::jit::recording::extended_asm
108 : : {
109 : : };
110 : :
111 : :
112 : : /**********************************************************************
113 : : Error-handling.
114 : :
115 : : We try to gracefully handle API usage errors by being defensive
116 : : at the API boundary.
117 : : **********************************************************************/
118 : :
119 : : #define JIT_BEGIN_STMT do {
120 : : #define JIT_END_STMT } while(0)
121 : :
122 : : /* Each of these error-handling macros determines if TEST_EXPR holds.
123 : :
124 : : If TEXT_EXPR fails to hold we return from the enclosing function and
125 : : print an error, either via adding an error on the given context CTXT
126 : : if CTXT is non-NULL, falling back to simply printing to stderr if CTXT
127 : : is NULL.
128 : :
129 : : They have to be macros since they inject their "return" into the
130 : : function they are placed in.
131 : :
132 : : The variant macros express:
133 : :
134 : : (A) whether or not we need to return a value:
135 : : RETURN_VAL_IF_FAIL* vs
136 : : RETURN_IF_FAIL*,
137 : : with the former returning RETURN_EXPR, and
138 : : RETURN_NULL_IF_FAIL*
139 : : for the common case where a NULL value is to be returned on
140 : : error, and
141 : :
142 : : (B) whether the error message is to be directly printed:
143 : : RETURN_*IF_FAIL
144 : : or is a format string with some number of arguments:
145 : : RETURN_*IF_FAIL_PRINTF*
146 : :
147 : : They all use JIT_BEGIN_STMT/JIT_END_STMT so they can be written with
148 : : trailing semicolons.
149 : : */
150 : :
151 : : #define RETURN_VAL_IF_FAIL(TEST_EXPR, RETURN_EXPR, CTXT, LOC, ERR_MSG) \
152 : : JIT_BEGIN_STMT \
153 : : if (!(TEST_EXPR)) \
154 : : { \
155 : : jit_error ((CTXT), (LOC), "%s: %s", __func__, (ERR_MSG)); \
156 : : return (RETURN_EXPR); \
157 : : } \
158 : : JIT_END_STMT
159 : :
160 : : #define RETURN_VAL_IF_FAIL_PRINTF1(TEST_EXPR, RETURN_EXPR, CTXT, LOC, ERR_FMT, A0) \
161 : : JIT_BEGIN_STMT \
162 : : if (!(TEST_EXPR)) \
163 : : { \
164 : : jit_error ((CTXT), (LOC), "%s: " ERR_FMT, \
165 : : __func__, (A0)); \
166 : : return (RETURN_EXPR); \
167 : : } \
168 : : JIT_END_STMT
169 : :
170 : : #define RETURN_VAL_IF_FAIL_PRINTF2(TEST_EXPR, RETURN_EXPR, CTXT, LOC, ERR_FMT, A0, A1) \
171 : : JIT_BEGIN_STMT \
172 : : if (!(TEST_EXPR)) \
173 : : { \
174 : : jit_error ((CTXT), (LOC), "%s: " ERR_FMT, \
175 : : __func__, (A0), (A1)); \
176 : : return (RETURN_EXPR); \
177 : : } \
178 : : JIT_END_STMT
179 : :
180 : : #define RETURN_VAL_IF_FAIL_PRINTF3(TEST_EXPR, RETURN_EXPR, CTXT, LOC, ERR_FMT, A0, A1, A2) \
181 : : JIT_BEGIN_STMT \
182 : : if (!(TEST_EXPR)) \
183 : : { \
184 : : jit_error ((CTXT), (LOC), "%s: " ERR_FMT, \
185 : : __func__, (A0), (A1), (A2)); \
186 : : return (RETURN_EXPR); \
187 : : } \
188 : : JIT_END_STMT
189 : :
190 : : #define RETURN_VAL_IF_FAIL_PRINTF4(TEST_EXPR, RETURN_EXPR, CTXT, LOC, ERR_FMT, A0, A1, A2, A3) \
191 : : JIT_BEGIN_STMT \
192 : : if (!(TEST_EXPR)) \
193 : : { \
194 : : jit_error ((CTXT), (LOC), "%s: " ERR_FMT, \
195 : : __func__, (A0), (A1), (A2), (A3)); \
196 : : return (RETURN_EXPR); \
197 : : } \
198 : : JIT_END_STMT
199 : :
200 : : #define RETURN_VAL_IF_FAIL_PRINTF5(TEST_EXPR, RETURN_EXPR, CTXT, LOC, ERR_FMT, A0, A1, A2, A3, A4) \
201 : : JIT_BEGIN_STMT \
202 : : if (!(TEST_EXPR)) \
203 : : { \
204 : : jit_error ((CTXT), (LOC), "%s: " ERR_FMT, \
205 : : __func__, (A0), (A1), (A2), (A3), (A4)); \
206 : : return (RETURN_EXPR); \
207 : : } \
208 : : JIT_END_STMT
209 : :
210 : : #define RETURN_VAL_IF_FAIL_PRINTF6(TEST_EXPR, RETURN_EXPR, CTXT, LOC, ERR_FMT, A0, A1, A2, A3, A4, A5) \
211 : : JIT_BEGIN_STMT \
212 : : if (!(TEST_EXPR)) \
213 : : { \
214 : : jit_error ((CTXT), (LOC), "%s: " ERR_FMT, \
215 : : __func__, (A0), (A1), (A2), (A3), (A4), (A5)); \
216 : : return (RETURN_EXPR); \
217 : : } \
218 : : JIT_END_STMT
219 : :
220 : : #define RETURN_NULL_IF_FAIL(TEST_EXPR, CTXT, LOC, ERR_MSG) \
221 : : RETURN_VAL_IF_FAIL ((TEST_EXPR), NULL, (CTXT), (LOC), (ERR_MSG))
222 : :
223 : : #define RETURN_NULL_IF_FAIL_PRINTF1(TEST_EXPR, CTXT, LOC, ERR_FMT, A0) \
224 : : RETURN_VAL_IF_FAIL_PRINTF1 (TEST_EXPR, NULL, CTXT, LOC, ERR_FMT, A0)
225 : :
226 : : #define RETURN_NULL_IF_FAIL_PRINTF2(TEST_EXPR, CTXT, LOC, ERR_FMT, A0, A1) \
227 : : RETURN_VAL_IF_FAIL_PRINTF2 (TEST_EXPR, NULL, CTXT, LOC, ERR_FMT, A0, A1)
228 : :
229 : : #define RETURN_NULL_IF_FAIL_PRINTF3(TEST_EXPR, CTXT, LOC, ERR_FMT, A0, A1, A2) \
230 : : RETURN_VAL_IF_FAIL_PRINTF3 (TEST_EXPR, NULL, CTXT, LOC, ERR_FMT, A0, A1, A2)
231 : :
232 : : #define RETURN_NULL_IF_FAIL_PRINTF4(TEST_EXPR, CTXT, LOC, ERR_FMT, A0, A1, A2, A3) \
233 : : RETURN_VAL_IF_FAIL_PRINTF4 (TEST_EXPR, NULL, CTXT, LOC, ERR_FMT, A0, A1, A2, A3)
234 : :
235 : : #define RETURN_NULL_IF_FAIL_PRINTF5(TEST_EXPR, CTXT, LOC, ERR_FMT, A0, A1, A2, A3, A4) \
236 : : RETURN_VAL_IF_FAIL_PRINTF5 (TEST_EXPR, NULL, CTXT, LOC, ERR_FMT, A0, A1, A2, A3, A4)
237 : :
238 : : #define RETURN_NULL_IF_FAIL_PRINTF6(TEST_EXPR, CTXT, LOC, ERR_FMT, A0, A1, A2, A3, A4, A5) \
239 : : RETURN_VAL_IF_FAIL_PRINTF6 (TEST_EXPR, NULL, CTXT, LOC, ERR_FMT, A0, A1, A2, A3, A4, A5)
240 : :
241 : : #define RETURN_IF_FAIL(TEST_EXPR, CTXT, LOC, ERR_MSG) \
242 : : JIT_BEGIN_STMT \
243 : : if (!(TEST_EXPR)) \
244 : : { \
245 : : jit_error ((CTXT), (LOC), "%s: %s", __func__, (ERR_MSG)); \
246 : : return; \
247 : : } \
248 : : JIT_END_STMT
249 : :
250 : : #define RETURN_IF_FAIL_PRINTF1(TEST_EXPR, CTXT, LOC, ERR_FMT, A0) \
251 : : JIT_BEGIN_STMT \
252 : : if (!(TEST_EXPR)) \
253 : : { \
254 : : jit_error ((CTXT), (LOC), "%s: " ERR_FMT, \
255 : : __func__, (A0)); \
256 : : return; \
257 : : } \
258 : : JIT_END_STMT
259 : :
260 : : #define RETURN_IF_FAIL_PRINTF2(TEST_EXPR, CTXT, LOC, ERR_FMT, A0, A1) \
261 : : JIT_BEGIN_STMT \
262 : : if (!(TEST_EXPR)) \
263 : : { \
264 : : jit_error ((CTXT), (LOC), "%s: " ERR_FMT, \
265 : : __func__, (A0), (A1)); \
266 : : return; \
267 : : } \
268 : : JIT_END_STMT
269 : :
270 : : #define RETURN_IF_FAIL_PRINTF4(TEST_EXPR, CTXT, LOC, ERR_FMT, A0, A1, A2, A3) \
271 : : JIT_BEGIN_STMT \
272 : : if (!(TEST_EXPR)) \
273 : : { \
274 : : jit_error ((CTXT), (LOC), "%s: " ERR_FMT, \
275 : : __func__, (A0), (A1), (A2), (A3)); \
276 : : return; \
277 : : } \
278 : : JIT_END_STMT
279 : :
280 : : /* Check that BLOCK is non-NULL, and that it's OK to add statements to
281 : : it. This will fail if BLOCK has already been terminated by some
282 : : kind of jump or a return. */
283 : : #define RETURN_IF_NOT_VALID_BLOCK(BLOCK, LOC) \
284 : : JIT_BEGIN_STMT \
285 : : RETURN_IF_FAIL ((BLOCK), NULL, (LOC), "NULL block"); \
286 : : RETURN_IF_FAIL_PRINTF2 ( \
287 : : !(BLOCK)->has_been_terminated (), \
288 : : (BLOCK)->get_context (), \
289 : : (LOC), \
290 : : "adding to terminated block: %s (already terminated by: %s)", \
291 : : (BLOCK)->get_debug_string (), \
292 : : (BLOCK)->get_last_statement ()->get_debug_string ()); \
293 : : JIT_END_STMT
294 : :
295 : : /* As RETURN_IF_NOT_VALID_BLOCK, but injecting a "return NULL;" if it
296 : : fails. */
297 : : #define RETURN_NULL_IF_NOT_VALID_BLOCK(BLOCK, LOC) \
298 : : JIT_BEGIN_STMT \
299 : : RETURN_NULL_IF_FAIL ((BLOCK), NULL, (LOC), "NULL block"); \
300 : : RETURN_NULL_IF_FAIL_PRINTF2 ( \
301 : : !(BLOCK)->has_been_terminated (), \
302 : : (BLOCK)->get_context (), \
303 : : (LOC), \
304 : : "adding to terminated block: %s (already terminated by: %s)", \
305 : : (BLOCK)->get_debug_string (), \
306 : : (BLOCK)->get_last_statement ()->get_debug_string ()); \
307 : : JIT_END_STMT
308 : :
309 : : /* Format the given string, and report it as an error, either on CTXT
310 : : if non-NULL, or by printing to stderr if we have a NULL context.
311 : : LOC gives the source location where the error occcurred, and can be
312 : : NULL. */
313 : :
314 : : static void
315 : : jit_error (gcc::jit::recording::context *ctxt,
316 : : gcc::jit::recording::location *loc,
317 : : const char *fmt, ...)
318 : : GNU_PRINTF(3, 4);
319 : :
320 : : static void
321 : 10131 : jit_error (gcc::jit::recording::context *ctxt,
322 : : gcc::jit::recording::location *loc,
323 : : const char *fmt, ...)
324 : : {
325 : 10131 : va_list ap;
326 : 10131 : va_start (ap, fmt);
327 : :
328 : 10131 : if (ctxt)
329 : 4837 : ctxt->add_error_va (loc, fmt, ap);
330 : : else
331 : : {
332 : : /* No context? Send to stderr. */
333 : 5294 : vfprintf (stderr, fmt, ap);
334 : 5294 : fprintf (stderr, "\n");
335 : : }
336 : :
337 : 10131 : va_end (ap);
338 : 10131 : }
339 : :
340 : : /* Determine whether or not we can write to lvalues of type LTYPE from
341 : : rvalues of type RTYPE, detecting type errors such as attempting to
342 : : write to an int with a string literal (without an explicit cast).
343 : :
344 : : This is implemented by calling the
345 : : gcc::jit::recording::type::accepts_writes_from virtual function on
346 : : LTYPE. */
347 : :
348 : : static bool
349 : 14392 : compatible_types (gcc::jit::recording::type *ltype,
350 : : gcc::jit::recording::type *rtype)
351 : : {
352 : 11029 : return ltype->accepts_writes_from (rtype);
353 : : }
354 : :
355 : : /* Public entrypoint wrapping compatible_types. */
356 : :
357 : : int
358 : 45 : gcc_jit_compatible_types (gcc_jit_type *ltype,
359 : : gcc_jit_type *rtype)
360 : : {
361 : 45 : RETURN_VAL_IF_FAIL (ltype, 0, NULL, NULL, "NULL ltype");
362 : 45 : RETURN_VAL_IF_FAIL (rtype, 0, NULL, NULL, "NULL rtype");
363 : 45 : return compatible_types (ltype, rtype);
364 : : }
365 : :
366 : : /* Public entrypoint for acquiring a gcc_jit_context.
367 : : Note that this creates a new top-level context; contrast with
368 : : gcc_jit_context_new_child_context below.
369 : :
370 : : The real work is done in the constructor for
371 : : gcc::jit::recording::context in jit-recording.cc. */
372 : :
373 : : gcc_jit_context *
374 : 1703 : gcc_jit_context_acquire (void)
375 : : {
376 : 1703 : gcc_jit_context *ctxt = new gcc_jit_context (NULL);
377 : 1703 : ctxt->log ("new top-level ctxt: %p", (void *)ctxt);
378 : 1703 : return ctxt;
379 : : }
380 : :
381 : : /* Public entrypoint for releasing a gcc_jit_context.
382 : : The real work is done in the destructor for
383 : : gcc::jit::recording::context in jit-recording.cc. */
384 : :
385 : : void
386 : 1713 : gcc_jit_context_release (gcc_jit_context *ctxt)
387 : : {
388 : 1713 : RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL ctxt");
389 : 1713 : JIT_LOG_FUNC (ctxt->get_logger ());
390 : 1713 : ctxt->log ("deleting ctxt: %p", (void *)ctxt);
391 : 1713 : delete ctxt;
392 : 1713 : }
393 : :
394 : : /* Public entrypoint for creating a child context within
395 : : PARENT_CTXT. See description in libgccjit.h.
396 : :
397 : : The real work is done in the constructor for
398 : : gcc::jit::recording::context in jit-recording.cc. */
399 : :
400 : : gcc_jit_context *
401 : 12 : gcc_jit_context_new_child_context (gcc_jit_context *parent_ctxt)
402 : : {
403 : 12 : RETURN_NULL_IF_FAIL (parent_ctxt, NULL, NULL, "NULL parent ctxt");
404 : 12 : JIT_LOG_FUNC (parent_ctxt->get_logger ());
405 : 12 : parent_ctxt->log ("parent_ctxt: %p", (void *)parent_ctxt);
406 : 12 : gcc_jit_context *child_ctxt = new gcc_jit_context (parent_ctxt);
407 : 12 : child_ctxt->log ("new child_ctxt: %p", (void *)child_ctxt);
408 : 12 : return child_ctxt;
409 : 12 : }
410 : :
411 : : /* Public entrypoint. See description in libgccjit.h.
412 : :
413 : : After error-checking, the real work is done by the
414 : : gcc::jit::recording::context::new_location
415 : : method in jit-recording.cc. */
416 : :
417 : : gcc_jit_location *
418 : 9717 : gcc_jit_context_new_location (gcc_jit_context *ctxt,
419 : : const char *filename,
420 : : int line,
421 : : int column)
422 : : {
423 : 9717 : RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
424 : 9717 : JIT_LOG_FUNC (ctxt->get_logger ());
425 : 9717 : return (gcc_jit_location *)ctxt->new_location (filename, line, column, true);
426 : 9717 : }
427 : :
428 : : /* Public entrypoint. See description in libgccjit.h.
429 : :
430 : : After error-checking, this calls the trivial
431 : : gcc::jit::recording::memento::as_object method (a location is a
432 : : memento), in jit-recording.h. */
433 : :
434 : : gcc_jit_object *
435 : 24 : gcc_jit_location_as_object (gcc_jit_location *loc)
436 : : {
437 : 24 : RETURN_NULL_IF_FAIL (loc, NULL, NULL, "NULL location");
438 : :
439 : 24 : return static_cast <gcc_jit_object *> (loc->as_object ());
440 : : }
441 : :
442 : : /* Public entrypoint. See description in libgccjit.h.
443 : :
444 : : After error-checking, this calls the trivial
445 : : gcc::jit::recording::memento::as_object method (a type is a
446 : : memento), in jit-recording.h. */
447 : :
448 : : gcc_jit_object *
449 : 427 : gcc_jit_type_as_object (gcc_jit_type *type)
450 : : {
451 : 427 : RETURN_NULL_IF_FAIL (type, NULL, NULL, "NULL type");
452 : :
453 : 427 : return static_cast <gcc_jit_object *> (type->as_object ());
454 : : }
455 : :
456 : : /* Public entrypoint for getting a specific type from a context.
457 : :
458 : : After error-checking, the real work is done by the
459 : : gcc::jit::recording::context::get_type method, in
460 : : jit-recording.cc */
461 : :
462 : : gcc_jit_type *
463 : 15924 : gcc_jit_context_get_type (gcc_jit_context *ctxt,
464 : : enum gcc_jit_types type)
465 : : {
466 : 15924 : RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
467 : 15924 : JIT_LOG_FUNC (ctxt->get_logger ());
468 : 15924 : RETURN_NULL_IF_FAIL_PRINTF1 (
469 : : (type >= GCC_JIT_TYPE_VOID
470 : : && type < NUM_GCC_JIT_TYPES),
471 : : ctxt, NULL,
472 : : "unrecognized value for enum gcc_jit_types: %i", type);
473 : :
474 : 15919 : return (gcc_jit_type *)ctxt->get_type (type);
475 : 15924 : }
476 : :
477 : : /* Public entrypoint for getting the integer type of the given size and
478 : : signedness.
479 : :
480 : : After error-checking, the real work is done by the
481 : : gcc::jit::recording::context::get_int_type method,
482 : : in jit-recording.cc. */
483 : :
484 : : gcc_jit_type *
485 : 136 : gcc_jit_context_get_int_type (gcc_jit_context *ctxt,
486 : : int num_bytes, int is_signed)
487 : : {
488 : 136 : RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
489 : 136 : JIT_LOG_FUNC (ctxt->get_logger ());
490 : 136 : RETURN_NULL_IF_FAIL (num_bytes >= 0, ctxt, NULL, "negative size");
491 : :
492 : 136 : return (gcc_jit_type *)ctxt->get_int_type (num_bytes, is_signed);
493 : 136 : }
494 : :
495 : : /* Public entrypoint. See description in libgccjit.h.
496 : :
497 : : After error-checking, the real work is done by the
498 : : gcc::jit::recording::type::get_pointer method, in
499 : : jit-recording.cc */
500 : :
501 : : gcc_jit_type *
502 : 1465 : gcc_jit_type_get_pointer (gcc_jit_type *type)
503 : : {
504 : 1465 : RETURN_NULL_IF_FAIL (type, NULL, NULL, "NULL type");
505 : :
506 : 1459 : return (gcc_jit_type *)type->get_pointer ();
507 : : }
508 : :
509 : : /* Public entrypoint. See description in libgccjit.h.
510 : :
511 : : After error-checking, the real work is done by the
512 : : gcc::jit::recording::type::get_const method, in
513 : : jit-recording.cc. */
514 : :
515 : : gcc_jit_type *
516 : 648 : gcc_jit_type_get_const (gcc_jit_type *type)
517 : : {
518 : 648 : RETURN_NULL_IF_FAIL (type, NULL, NULL, "NULL type");
519 : :
520 : 646 : return (gcc_jit_type *)type->get_const ();
521 : : }
522 : :
523 : : /* Public entrypoint. See description in libgccjit.h.
524 : :
525 : : After error-checking, the real work is done by the
526 : : gcc::jit::recording::type::get_volatile method, in
527 : : jit-recording.cc. */
528 : :
529 : : gcc_jit_type *
530 : 257 : gcc_jit_type_get_volatile (gcc_jit_type *type)
531 : : {
532 : 257 : RETURN_NULL_IF_FAIL (type, NULL, NULL, "NULL type");
533 : :
534 : 251 : return (gcc_jit_type *)type->get_volatile ();
535 : : }
536 : :
537 : : /* Public entrypoint. See description in libgccjit.h.
538 : :
539 : : After error-checking, the real work is done by the
540 : : gcc::jit::recording::type::get_restrict method, in
541 : : jit-recording.cc. */
542 : :
543 : : gcc_jit_type *
544 : 10 : gcc_jit_type_get_restrict (gcc_jit_type *type)
545 : : {
546 : 10 : RETURN_NULL_IF_FAIL (type, NULL, NULL, "NULL type");
547 : 10 : RETURN_NULL_IF_FAIL (type->is_pointer (), NULL, NULL, "not a pointer type");
548 : :
549 : 10 : return (gcc_jit_type *)type->get_restrict ();
550 : : }
551 : :
552 : : /* Public entrypoint. See description in libgccjit.h.
553 : :
554 : : After error-checking, the real work is done by the
555 : : gcc::jit::recording::type::get_size method, in
556 : : jit-recording.cc. */
557 : :
558 : : ssize_t
559 : 40 : gcc_jit_type_get_size (gcc_jit_type *type)
560 : : {
561 : 40 : RETURN_VAL_IF_FAIL (type, -1, NULL, NULL, "NULL type");
562 : 40 : RETURN_VAL_IF_FAIL
563 : : (type->is_int () || type->is_float () || type->is_pointer (), -1, NULL, NULL,
564 : : "only getting the size of integer or floating-point or pointer types is supported for now");
565 : 40 : return type->get_size ();
566 : : }
567 : :
568 : : /* Public entrypoint. See description in libgccjit.h.
569 : :
570 : : After error-checking, the real work is done by the
571 : : gcc::jit::recording::type::is_array method, in
572 : : jit-recording.cc. */
573 : :
574 : : gcc_jit_type *
575 : 30 : gcc_jit_type_dyncast_array (gcc_jit_type *type)
576 : : {
577 : 30 : RETURN_NULL_IF_FAIL (type, NULL, NULL, "NULL type");
578 : :
579 : 30 : return (gcc_jit_type *)type->is_array ();
580 : : }
581 : :
582 : : /* Public entrypoint. See description in libgccjit.h.
583 : :
584 : : After error-checking, the real work is done by the
585 : : gcc::jit::recording::type::is_bool method, in
586 : : jit-recording.cc. */
587 : :
588 : : int
589 : 30 : gcc_jit_type_is_bool (gcc_jit_type *type)
590 : : {
591 : 30 : RETURN_VAL_IF_FAIL (type, FALSE, NULL, NULL, "NULL type");
592 : :
593 : 30 : return type->is_bool ();
594 : : }
595 : :
596 : : /* Public entrypoint. See description in libgccjit.h.
597 : :
598 : : After error-checking, the real work is done by the
599 : : gcc::jit::recording::type::is_pointer method, in
600 : : jit-recording.cc. */
601 : :
602 : : gcc_jit_type *
603 : 30 : gcc_jit_type_is_pointer (gcc_jit_type *type)
604 : : {
605 : 30 : RETURN_NULL_IF_FAIL (type, NULL, NULL, "NULL type");
606 : :
607 : 30 : return (gcc_jit_type *)type->is_pointer ();
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::type::is_int method, in
614 : : jit-recording.cc. */
615 : :
616 : : int
617 : 105 : gcc_jit_type_is_integral (gcc_jit_type *type)
618 : : {
619 : 105 : RETURN_VAL_IF_FAIL (type, FALSE, NULL, NULL, "NULL type");
620 : :
621 : 105 : return type->is_int ();
622 : : }
623 : :
624 : : /* Public entrypoint. See description in libgccjit.h.
625 : :
626 : : After error-checking, the real work is done by the
627 : : gcc::jit::recording::type::is_vector method, in
628 : : jit-recording.cc. */
629 : :
630 : : gcc_jit_vector_type *
631 : 30 : gcc_jit_type_dyncast_vector (gcc_jit_type *type)
632 : : {
633 : 30 : RETURN_NULL_IF_FAIL (type, NULL, NULL, "NULL type");
634 : 30 : gcc::jit::recording::vector_type *vector_type = type->is_vector ();
635 : 30 : return (gcc_jit_vector_type *)vector_type;
636 : : }
637 : :
638 : : /* Public entrypoint. See description in libgccjit.h.
639 : :
640 : : After error-checking, the real work is done by the
641 : : gcc::jit::recording::type::is_struct method, in
642 : : jit-recording.cc. */
643 : :
644 : : gcc_jit_struct *
645 : 30 : gcc_jit_type_is_struct (gcc_jit_type *type)
646 : : {
647 : 30 : RETURN_NULL_IF_FAIL (type, NULL, NULL, "NULL type");
648 : 30 : gcc::jit::recording::struct_ *struct_type = type->is_struct ();
649 : 30 : return (gcc_jit_struct *)struct_type;
650 : : }
651 : :
652 : : /* Public entrypoint. See description in libgccjit.h.
653 : :
654 : : After error-checking, the real work is done by the
655 : : gcc::jit::recording::vector_type::get_num_units method, in
656 : : jit-recording.cc. */
657 : :
658 : : size_t
659 : 15 : gcc_jit_vector_type_get_num_units (gcc_jit_vector_type *vector_type)
660 : : {
661 : 15 : RETURN_VAL_IF_FAIL (vector_type, 0, NULL, NULL, "NULL vector_type");
662 : 15 : return vector_type->get_num_units ();
663 : : }
664 : :
665 : : /* Public entrypoint. See description in libgccjit.h.
666 : :
667 : : After error-checking, the real work is done by the
668 : : gcc::jit::recording::vector_type::get_element_type method, in
669 : : jit-recording.cc. */
670 : :
671 : : gcc_jit_type *
672 : 15 : gcc_jit_vector_type_get_element_type (gcc_jit_vector_type *vector_type)
673 : : {
674 : 15 : RETURN_NULL_IF_FAIL (vector_type, NULL, NULL, "NULL vector_type");
675 : 15 : return (gcc_jit_type *)vector_type->get_element_type ();
676 : : }
677 : :
678 : : /* Public entrypoint. See description in libgccjit.h.
679 : :
680 : : After error-checking, the real work is done by the
681 : : gcc::jit::recording::type::unqualified method, in
682 : : jit-recording.cc. */
683 : :
684 : : gcc_jit_type *
685 : 45 : gcc_jit_type_unqualified (gcc_jit_type *type)
686 : : {
687 : 45 : RETURN_NULL_IF_FAIL (type, NULL, NULL, "NULL type");
688 : :
689 : 45 : return (gcc_jit_type *)type->unqualified ();
690 : : }
691 : :
692 : : /* Public entrypoint. See description in libgccjit.h.
693 : :
694 : : After error-checking, the real work is done by the
695 : : gcc::jit::recording::type::dyn_cast_function_type method, in
696 : : jit-recording.cc. */
697 : :
698 : : gcc_jit_function_type *
699 : 30 : gcc_jit_type_dyncast_function_ptr_type (gcc_jit_type *type)
700 : : {
701 : 30 : RETURN_NULL_IF_FAIL (type, NULL, NULL, "NULL type");
702 : 30 : gcc::jit::recording::type *func_ptr_type = type->dereference ();
703 : 30 : if (!func_ptr_type)
704 : : {
705 : : return NULL;
706 : : }
707 : :
708 : 15 : return (gcc_jit_function_type *)func_ptr_type->dyn_cast_function_type ();
709 : : }
710 : :
711 : : /* Public entrypoint. See description in libgccjit.h.
712 : :
713 : : After error-checking, the real work is done by the
714 : : gcc::jit::recording::function_type::get_return_type method, in
715 : : jit-recording.cc. */
716 : :
717 : : gcc_jit_type *
718 : 15 : gcc_jit_function_type_get_return_type (gcc_jit_function_type *function_type)
719 : : {
720 : 15 : RETURN_NULL_IF_FAIL (function_type, NULL, NULL, "NULL function_type");
721 : 15 : return (gcc_jit_type *)function_type->get_return_type ();
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::function_type::get_param_types method, in
728 : : jit-recording.cc. */
729 : :
730 : : size_t
731 : 15 : gcc_jit_function_type_get_param_count (gcc_jit_function_type *function_type)
732 : : {
733 : 15 : RETURN_VAL_IF_FAIL (function_type, 0, NULL, NULL, "NULL function_type");
734 : 30 : return function_type->get_param_types ().length ();
735 : : }
736 : :
737 : : /* Public entrypoint. See description in libgccjit.h.
738 : :
739 : : After error-checking, the real work is done by the
740 : : gcc::jit::recording::function_type::get_param_types method, in
741 : : jit-recording.cc. */
742 : :
743 : : gcc_jit_type *
744 : 30 : gcc_jit_function_type_get_param_type (gcc_jit_function_type *function_type,
745 : : size_t index)
746 : : {
747 : 30 : RETURN_NULL_IF_FAIL (function_type, NULL, NULL, "NULL function_type");
748 : 30 : size_t num_params = function_type->get_param_types ().length ();
749 : 30 : gcc::jit::recording::context *ctxt = function_type->m_ctxt;
750 : 30 : RETURN_NULL_IF_FAIL_PRINTF3 (index < num_params,
751 : : ctxt, NULL,
752 : : "index of %zu is too large (%s has %zu params)",
753 : : index,
754 : : function_type->get_debug_string (),
755 : : num_params);
756 : 30 : return (gcc_jit_type *)function_type->get_param_types ()[index];
757 : : }
758 : :
759 : : /* Public entrypoint. See description in libgccjit.h.
760 : :
761 : : After error-checking, the real work is done by the
762 : : gcc::jit::recording::context::new_array_type method, in
763 : : jit-recording.cc. */
764 : :
765 : : gcc_jit_type *
766 : 330 : gcc_jit_context_new_array_type (gcc_jit_context *ctxt,
767 : : gcc_jit_location *loc,
768 : : gcc_jit_type *element_type,
769 : : int num_elements)
770 : : {
771 : 330 : RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
772 : 330 : JIT_LOG_FUNC (ctxt->get_logger ());
773 : : /* LOC can be NULL. */
774 : 330 : RETURN_NULL_IF_FAIL (element_type, ctxt, loc, "NULL type");
775 : 330 : RETURN_NULL_IF_FAIL (num_elements >= 0, ctxt, NULL, "negative size");
776 : 330 : RETURN_NULL_IF_FAIL (!element_type->is_void (), ctxt, loc,
777 : : "void type for elements");
778 : :
779 : 330 : return (gcc_jit_type *)ctxt->new_array_type (loc,
780 : : element_type,
781 : 330 : num_elements);
782 : 330 : }
783 : :
784 : : /* Public entrypoint. See description in libgccjit.h.
785 : :
786 : : After error-checking, the real work is done by the
787 : : gcc::jit::recording::context::new_field method, in
788 : : jit-recording.cc. */
789 : :
790 : : gcc_jit_field *
791 : 4577 : gcc_jit_context_new_field (gcc_jit_context *ctxt,
792 : : gcc_jit_location *loc,
793 : : gcc_jit_type *type,
794 : : const char *name)
795 : : {
796 : 4577 : RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
797 : 4577 : JIT_LOG_FUNC (ctxt->get_logger ());
798 : : /* LOC can be NULL. */
799 : 4577 : RETURN_NULL_IF_FAIL (type, ctxt, loc, "NULL type");
800 : 4511 : RETURN_NULL_IF_FAIL (name, ctxt, loc, "NULL name");
801 : 4511 : RETURN_NULL_IF_FAIL_PRINTF2 (
802 : : type->has_known_size (),
803 : : ctxt, loc,
804 : : "unknown size for field \"%s\" (type: %s)",
805 : : name,
806 : : type->get_debug_string ());
807 : 4506 : RETURN_NULL_IF_FAIL_PRINTF1 (
808 : : !type->is_void (),
809 : : ctxt, loc,
810 : : "void type for field \"%s\"",
811 : : name);
812 : :
813 : 4370 : return (gcc_jit_field *)ctxt->new_field (loc, type, name);
814 : 4577 : }
815 : :
816 : : /* Public entrypoint. See description in libgccjit.h.
817 : :
818 : : After error-checking, the real work is done by the
819 : : gcc::jit::recording::context::new_bitfield method, in
820 : : jit-recording.cc. */
821 : :
822 : : gcc_jit_field *
823 : 115 : gcc_jit_context_new_bitfield (gcc_jit_context *ctxt,
824 : : gcc_jit_location *loc,
825 : : gcc_jit_type *type,
826 : : int width,
827 : : const char *name)
828 : : {
829 : 115 : RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
830 : 115 : JIT_LOG_FUNC (ctxt->get_logger ());
831 : : /* LOC can be NULL. */
832 : 115 : RETURN_NULL_IF_FAIL (name, ctxt, loc, "NULL name");
833 : 115 : RETURN_NULL_IF_FAIL (type, ctxt, loc, "NULL type");
834 : 115 : RETURN_NULL_IF_FAIL_PRINTF2 (type->is_int () || type->is_bool (),
835 : : ctxt, loc,
836 : : "bit-field %s has non integral type %s",
837 : : name, type->get_debug_string ());
838 : 110 : RETURN_NULL_IF_FAIL_PRINTF2 (
839 : : width > 0, ctxt, loc,
840 : : "invalid width %d for bitfield \"%s\" (must be > 0)",
841 : : width, name);
842 : 110 : RETURN_NULL_IF_FAIL_PRINTF2 (
843 : : type->has_known_size (),
844 : : ctxt, loc,
845 : : "unknown size for field \"%s\" (type: %s)",
846 : : name,
847 : : type->get_debug_string ());
848 : :
849 : 110 : return (gcc_jit_field *)ctxt->new_bitfield (loc, type, width, name);
850 : 115 : }
851 : :
852 : : /* Public entrypoint. See description in libgccjit.h.
853 : :
854 : : After error-checking, this calls the trivial
855 : : gcc::jit::recording::memento::as_object method (a field is a
856 : : memento), in jit-recording.h. */
857 : :
858 : : gcc_jit_object *
859 : 110 : gcc_jit_field_as_object (gcc_jit_field *field)
860 : : {
861 : 110 : RETURN_NULL_IF_FAIL (field, NULL, NULL, "NULL field");
862 : :
863 : 110 : return static_cast <gcc_jit_object *> (field->as_object ());
864 : : }
865 : :
866 : : /* Public entrypoint. See description in libgccjit.h.
867 : :
868 : : After error-checking, the real work is done by the
869 : : gcc::jit::recording::context::new_struct_type method,
870 : : immediately followed by a "set_fields" call on the resulting
871 : : gcc::jit::recording::compound_type *, both in jit-recording.cc */
872 : :
873 : : gcc_jit_struct *
874 : 997 : gcc_jit_context_new_struct_type (gcc_jit_context *ctxt,
875 : : gcc_jit_location *loc,
876 : : const char *name,
877 : : int num_fields,
878 : : gcc_jit_field **fields)
879 : : {
880 : 997 : RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
881 : 997 : JIT_LOG_FUNC (ctxt->get_logger ());
882 : : /* LOC can be NULL. */
883 : 997 : RETURN_NULL_IF_FAIL (name, ctxt, loc, "NULL name");
884 : 997 : if (num_fields)
885 : 939 : RETURN_NULL_IF_FAIL (fields, ctxt, loc, "NULL fields ptr");
886 : 4581 : for (int i = 0; i < num_fields; i++)
887 : : {
888 : 3764 : RETURN_NULL_IF_FAIL (fields[i], ctxt, loc, "NULL field ptr");
889 : 3584 : RETURN_NULL_IF_FAIL_PRINTF2 (
890 : : fields[i]->get_container () == NULL,
891 : : ctxt, loc,
892 : : "%s is already a field of %s",
893 : : fields[i]->get_debug_string (),
894 : : fields[i]->get_container ()->get_debug_string ());
895 : : }
896 : :
897 : 817 : gcc::jit::recording::struct_ *result =
898 : 817 : ctxt->new_struct_type (loc, name);
899 : 817 : result->set_fields (loc,
900 : : num_fields,
901 : : (gcc::jit::recording::field **)fields);
902 : 817 : return static_cast<gcc_jit_struct *> (result);
903 : 997 : }
904 : :
905 : : /* Public entrypoint. See description in libgccjit.h.
906 : :
907 : : After error-checking, the real work is done by the
908 : : gcc::jit::recording::context::new_struct_type method in
909 : : jit-recording.cc. */
910 : :
911 : : gcc_jit_struct *
912 : 120 : gcc_jit_context_new_opaque_struct (gcc_jit_context *ctxt,
913 : : gcc_jit_location *loc,
914 : : const char *name)
915 : : {
916 : 120 : RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
917 : 120 : JIT_LOG_FUNC (ctxt->get_logger ());
918 : : /* LOC can be NULL. */
919 : 120 : RETURN_NULL_IF_FAIL (name, ctxt, loc, "NULL name");
920 : :
921 : 120 : return (gcc_jit_struct *)ctxt->new_struct_type (loc, name);
922 : 120 : }
923 : :
924 : : /* Public entrypoint. See description in libgccjit.h.
925 : :
926 : : After error-checking, this calls the trivial
927 : : gcc::jit::recording::struct_::as_object method in
928 : : jit-recording.h. */
929 : :
930 : : gcc_jit_type *
931 : 1162 : gcc_jit_struct_as_type (gcc_jit_struct *struct_type)
932 : : {
933 : 1162 : RETURN_NULL_IF_FAIL (struct_type, NULL, NULL, "NULL struct_type");
934 : :
935 : 982 : return static_cast <gcc_jit_type *> (struct_type->as_type ());
936 : : }
937 : :
938 : : /* Public entrypoint. See description in libgccjit.h.
939 : :
940 : : After error-checking, the real work is done by the
941 : : gcc::jit::recording::compound_type::set_fields method in
942 : : jit-recording.cc. */
943 : :
944 : : void
945 : 90 : gcc_jit_struct_set_fields (gcc_jit_struct *struct_type,
946 : : gcc_jit_location *loc,
947 : : int num_fields,
948 : : gcc_jit_field **fields)
949 : : {
950 : 90 : RETURN_IF_FAIL (struct_type, NULL, loc, "NULL struct_type");
951 : 90 : gcc::jit::recording::context *ctxt = struct_type->m_ctxt;
952 : 90 : JIT_LOG_FUNC (ctxt->get_logger ());
953 : : /* LOC can be NULL. */
954 : 90 : RETURN_IF_FAIL_PRINTF1 (
955 : : struct_type->get_fields () == NULL, ctxt, loc,
956 : : "%s already has had fields set",
957 : : struct_type->get_debug_string ());
958 : 90 : if (num_fields)
959 : 90 : RETURN_IF_FAIL (fields, ctxt, loc, "NULL fields ptr");
960 : 255 : for (int i = 0; i < num_fields; i++)
961 : : {
962 : 165 : RETURN_IF_FAIL_PRINTF2 (
963 : : fields[i],
964 : : ctxt, loc,
965 : : "%s: NULL field ptr at index %i",
966 : : struct_type->get_debug_string (),
967 : : i);
968 : 165 : RETURN_IF_FAIL_PRINTF2 (
969 : : fields[i]->get_container () == NULL,
970 : : ctxt, loc,
971 : : "%s is already a field of %s",
972 : : fields[i]->get_debug_string (),
973 : : fields[i]->get_container ()->get_debug_string ());
974 : : }
975 : :
976 : 90 : struct_type->set_fields (loc, num_fields,
977 : : (gcc::jit::recording::field **)fields);
978 : 90 : }
979 : :
980 : :
981 : : /* Public entrypoint. See description in libgccjit.h.
982 : :
983 : : After error-checking, the real work is done by the
984 : : gcc::jit::recording::fields::get_field method in
985 : : jit-recording.cc. */
986 : : extern gcc_jit_field *
987 : 30 : gcc_jit_struct_get_field (gcc_jit_struct *struct_type,
988 : : size_t index)
989 : : {
990 : 30 : RETURN_NULL_IF_FAIL (struct_type, NULL, NULL, "NULL struct type");
991 : 30 : RETURN_NULL_IF_FAIL (struct_type->get_fields (), NULL, NULL,
992 : : "NULL struct fields");
993 : 30 : size_t num_fields = struct_type->get_fields ()->length ();
994 : 30 : RETURN_NULL_IF_FAIL_PRINTF3 (index < num_fields,
995 : : NULL, NULL,
996 : : "index of %zu is too large (%s has %zu fields)",
997 : : index,
998 : : struct_type->get_debug_string (),
999 : : num_fields);
1000 : 30 : return (gcc_jit_field *)struct_type->get_fields ()->get_field (index);
1001 : : }
1002 : :
1003 : : /* Public entrypoint. See description in libgccjit.h.
1004 : :
1005 : : After error-checking, this calls the trivial
1006 : : gcc::jit::recording::struct_::get_fields method in
1007 : : jit-recording.h. */
1008 : :
1009 : : size_t
1010 : 15 : gcc_jit_struct_get_field_count (gcc_jit_struct *struct_type)
1011 : : {
1012 : 15 : RETURN_VAL_IF_FAIL (struct_type, 0, NULL, NULL, "NULL struct type");
1013 : 30 : return struct_type->get_fields ()->length ();
1014 : : }
1015 : :
1016 : : /* Public entrypoint. See description in libgccjit.h.
1017 : :
1018 : : After error-checking, the real work is done by the
1019 : : gcc::jit::recording::context::new_union_type method,
1020 : : immediately followed by a "set_fields" call on the resulting
1021 : : gcc::jit::recording::compound_type *, both in jit-recording.cc */
1022 : :
1023 : : gcc_jit_type *
1024 : 85 : gcc_jit_context_new_union_type (gcc_jit_context *ctxt,
1025 : : gcc_jit_location *loc,
1026 : : const char *name,
1027 : : int num_fields,
1028 : : gcc_jit_field **fields)
1029 : : {
1030 : 85 : RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
1031 : 85 : JIT_LOG_FUNC (ctxt->get_logger ());
1032 : : /* LOC can be NULL. */
1033 : 85 : RETURN_NULL_IF_FAIL (name, ctxt, loc, "NULL name");
1034 : 85 : if (num_fields)
1035 : 85 : RETURN_NULL_IF_FAIL (fields, ctxt, loc, "NULL fields ptr");
1036 : 275 : for (int i = 0; i < num_fields; i++)
1037 : : {
1038 : 190 : RETURN_NULL_IF_FAIL (fields[i], ctxt, loc, "NULL field ptr");
1039 : 190 : RETURN_NULL_IF_FAIL_PRINTF2 (
1040 : : fields[i]->get_container () == NULL,
1041 : : ctxt, loc,
1042 : : "%s is already a field of %s",
1043 : : fields[i]->get_debug_string (),
1044 : : fields[i]->get_container ()->get_debug_string ());
1045 : : }
1046 : :
1047 : 85 : gcc::jit::recording::union_ *result =
1048 : 85 : ctxt->new_union_type (loc, name);
1049 : 85 : result->set_fields (loc,
1050 : : num_fields,
1051 : : (gcc::jit::recording::field **)fields);
1052 : 85 : return (gcc_jit_type *) (result);
1053 : 85 : }
1054 : :
1055 : : /* Public entrypoint. See description in libgccjit.h.
1056 : :
1057 : : After error-checking, the real work is done by the
1058 : : gcc::jit::recording::context::new_function_ptr_type method,
1059 : : in jit-recording.cc */
1060 : :
1061 : : gcc_jit_type *
1062 : 70 : gcc_jit_context_new_function_ptr_type (gcc_jit_context *ctxt,
1063 : : gcc_jit_location *loc,
1064 : : gcc_jit_type *return_type,
1065 : : int num_params,
1066 : : gcc_jit_type **param_types,
1067 : : int is_variadic)
1068 : : {
1069 : 70 : RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
1070 : 70 : JIT_LOG_FUNC (ctxt->get_logger ());
1071 : : /* LOC can be NULL. */
1072 : 70 : RETURN_NULL_IF_FAIL (return_type, ctxt, loc, "NULL return_type");
1073 : 70 : RETURN_NULL_IF_FAIL (
1074 : : (num_params == 0) || param_types,
1075 : : ctxt, loc,
1076 : : "NULL param_types creating function pointer type");
1077 : 200 : for (int i = 0; i < num_params; i++)
1078 : : {
1079 : 130 : RETURN_NULL_IF_FAIL_PRINTF1 (param_types[i],
1080 : : ctxt, loc,
1081 : : "NULL parameter type %i"
1082 : : " creating function pointer type", i);
1083 : 130 : RETURN_NULL_IF_FAIL_PRINTF1 (!param_types[i]->is_void (),
1084 : : ctxt, loc,
1085 : : "void type for param %i", i);
1086 : : }
1087 : :
1088 : 70 : return (gcc_jit_type*)
1089 : 70 : ctxt->new_function_ptr_type (loc, return_type,
1090 : : num_params,
1091 : : (gcc::jit::recording::type **)param_types,
1092 : 70 : is_variadic);
1093 : 70 : }
1094 : :
1095 : : /* Constructing functions. */
1096 : :
1097 : : /* Public entrypoint. See description in libgccjit.h.
1098 : :
1099 : : After error-checking, the real work is done by the
1100 : : gcc::jit::recording::context::new_param method, in jit-recording.cc */
1101 : :
1102 : : gcc_jit_param *
1103 : 8582 : gcc_jit_context_new_param (gcc_jit_context *ctxt,
1104 : : gcc_jit_location *loc,
1105 : : gcc_jit_type *type,
1106 : : const char *name)
1107 : : {
1108 : 8582 : RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
1109 : 8582 : JIT_LOG_FUNC (ctxt->get_logger ());
1110 : : /* LOC can be NULL. */
1111 : 8582 : RETURN_NULL_IF_FAIL (type, ctxt, loc, "NULL type");
1112 : 8412 : RETURN_NULL_IF_FAIL (name, ctxt, loc, "NULL name");
1113 : 8412 : RETURN_NULL_IF_FAIL_PRINTF1 (!type->is_void (),
1114 : : ctxt, loc,
1115 : : "void type for param \"%s\"", name);
1116 : :
1117 : 8279 : return (gcc_jit_param *)ctxt->new_param (loc, type, name);
1118 : 8582 : }
1119 : :
1120 : : /* Public entrypoint. See description in libgccjit.h.
1121 : :
1122 : : After error-checking, this calls the trivial
1123 : : gcc::jit::recording::memento::as_object method (a param is a memento),
1124 : : in jit-recording.h. */
1125 : :
1126 : : gcc_jit_object *
1127 : 0 : gcc_jit_param_as_object (gcc_jit_param *param)
1128 : : {
1129 : 0 : RETURN_NULL_IF_FAIL (param, NULL, NULL, "NULL param");
1130 : :
1131 : 0 : return static_cast <gcc_jit_object *> (param->as_object ());
1132 : : }
1133 : :
1134 : : /* Public entrypoint. See description in libgccjit.h.
1135 : :
1136 : : After error-checking, this calls the trivial
1137 : : gcc::jit::recording::param::as_lvalue method in jit-recording.h. */
1138 : :
1139 : : gcc_jit_lvalue *
1140 : 1934 : gcc_jit_param_as_lvalue (gcc_jit_param *param)
1141 : : {
1142 : 1934 : RETURN_NULL_IF_FAIL (param, NULL, NULL, "NULL param");
1143 : :
1144 : 1758 : return (gcc_jit_lvalue *)param->as_lvalue ();
1145 : : }
1146 : :
1147 : : /* Public entrypoint. See description in libgccjit.h.
1148 : :
1149 : : After error-checking, this calls the trivial
1150 : : gcc::jit::recording::lvalue::as_rvalue method (a param is an rvalue),
1151 : : in jit-recording.h. */
1152 : :
1153 : : gcc_jit_rvalue *
1154 : 5386 : gcc_jit_param_as_rvalue (gcc_jit_param *param)
1155 : : {
1156 : 5386 : RETURN_NULL_IF_FAIL (param, NULL, NULL, "NULL param");
1157 : :
1158 : 5386 : return (gcc_jit_rvalue *)param->as_rvalue ();
1159 : : }
1160 : :
1161 : : /* Public entrypoint. See description in libgccjit.h.
1162 : :
1163 : : After error-checking, the real work is done by the
1164 : : gcc::jit::recording::context::new_function method, in
1165 : : jit-recording.cc. */
1166 : :
1167 : : gcc_jit_function *
1168 : 4510 : gcc_jit_context_new_function (gcc_jit_context *ctxt,
1169 : : gcc_jit_location *loc,
1170 : : enum gcc_jit_function_kind kind,
1171 : : gcc_jit_type *return_type,
1172 : : const char *name,
1173 : : int num_params,
1174 : : gcc_jit_param **params,
1175 : : int is_variadic)
1176 : : {
1177 : 4510 : RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
1178 : 4510 : JIT_LOG_FUNC (ctxt->get_logger ());
1179 : : /* LOC can be NULL. */
1180 : 4510 : RETURN_NULL_IF_FAIL_PRINTF1 (
1181 : : ((kind >= GCC_JIT_FUNCTION_EXPORTED)
1182 : : && (kind <= GCC_JIT_FUNCTION_ALWAYS_INLINE)),
1183 : : ctxt, loc,
1184 : : "unrecognized value for enum gcc_jit_function_kind: %i",
1185 : : kind);
1186 : 4505 : RETURN_NULL_IF_FAIL (return_type, ctxt, loc, "NULL return_type");
1187 : 4464 : RETURN_NULL_IF_FAIL (name, ctxt, loc, "NULL name");
1188 : : /* The assembler can only handle certain names, so for now, enforce
1189 : : C's rules for identifiers upon the name, using ISALPHA and ISALNUM
1190 : : from safe-ctype.h to ignore the current locale.
1191 : : Eventually we'll need some way to interact with e.g. C++ name
1192 : : mangling. */
1193 : 4464 : {
1194 : : /* Leading char: */
1195 : 4464 : char ch = *name;
1196 : 4464 : RETURN_NULL_IF_FAIL_PRINTF2 (
1197 : : ISALPHA (ch) || ch == '_',
1198 : : ctxt, loc,
1199 : : "name \"%s\" contains invalid character: '%c'",
1200 : : name, ch);
1201 : : /* Subsequent chars: */
1202 : 1062509 : for (const char *ptr = name + 1; (ch = *ptr); ptr++)
1203 : : {
1204 : 1058045 : RETURN_NULL_IF_FAIL_PRINTF2 (
1205 : : ISALNUM (ch) || ch == '_',
1206 : : ctxt, loc,
1207 : : "name \"%s\" contains invalid character: '%c'",
1208 : : name, ch);
1209 : : }
1210 : : }
1211 : 4464 : RETURN_NULL_IF_FAIL_PRINTF1 (
1212 : : (num_params == 0) || params,
1213 : : ctxt, loc,
1214 : : "NULL params creating function %s", name);
1215 : 11985 : for (int i = 0; i < num_params; i++)
1216 : : {
1217 : 7750 : RETURN_NULL_IF_FAIL_PRINTF2 (
1218 : : params[i],
1219 : : ctxt, loc,
1220 : : "NULL parameter %i creating function %s", i, name);
1221 : 7526 : RETURN_NULL_IF_FAIL_PRINTF5 (
1222 : : params[i]->get_scope () == NULL,
1223 : : ctxt, loc,
1224 : : "parameter %i \"%s\""
1225 : : " (type: %s)"
1226 : : " for function %s"
1227 : : " was already used for function %s",
1228 : : i, params[i]->get_debug_string (),
1229 : : params[i]->get_type ()->get_debug_string (),
1230 : : name,
1231 : : params[i]->get_scope ()->get_debug_string ());
1232 : : }
1233 : :
1234 : 4235 : return (gcc_jit_function*)
1235 : 4235 : ctxt->new_function (loc, kind, return_type, name,
1236 : : num_params,
1237 : : (gcc::jit::recording::param **)params,
1238 : : is_variadic,
1239 : 4235 : BUILT_IN_NONE);
1240 : 4510 : }
1241 : :
1242 : : /* Public entrypoint. See description in libgccjit.h.
1243 : :
1244 : : After error-checking, the real work is done by the
1245 : : gcc::jit::recording::context::get_builtin_function method, in
1246 : : jit-recording.cc. */
1247 : :
1248 : : gcc_jit_function *
1249 : 255 : gcc_jit_context_get_builtin_function (gcc_jit_context *ctxt,
1250 : : const char *name)
1251 : : {
1252 : 255 : RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
1253 : 255 : JIT_LOG_FUNC (ctxt->get_logger ());
1254 : 255 : RETURN_NULL_IF_FAIL (name, ctxt, NULL, "NULL name");
1255 : :
1256 : 255 : return static_cast <gcc_jit_function *> (ctxt->get_builtin_function (name));
1257 : 255 : }
1258 : :
1259 : : /* Public entrypoint. See description in libgccjit.h.
1260 : :
1261 : : After error-checking, this calls the trivial
1262 : : gcc::jit::recording::memento::as_object method (a function is a
1263 : : memento), in jit-recording.h. */
1264 : :
1265 : : gcc_jit_object *
1266 : 151 : gcc_jit_function_as_object (gcc_jit_function *func)
1267 : : {
1268 : 151 : RETURN_NULL_IF_FAIL (func, NULL, NULL, "NULL function");
1269 : :
1270 : 151 : return static_cast <gcc_jit_object *> (func->as_object ());
1271 : : }
1272 : :
1273 : : /* Public entrypoint. See description in libgccjit.h.
1274 : :
1275 : : After error-checking, the real work is done by the
1276 : : gcc::jit::recording::function::get_param method, in
1277 : : jit-recording.h. */
1278 : :
1279 : : gcc_jit_param *
1280 : 30 : gcc_jit_function_get_param (gcc_jit_function *func, int index)
1281 : : {
1282 : 30 : RETURN_NULL_IF_FAIL (func, NULL, NULL, "NULL function");
1283 : 30 : gcc::jit::recording::context *ctxt = func->m_ctxt;
1284 : 30 : JIT_LOG_FUNC (ctxt->get_logger ());
1285 : 30 : RETURN_NULL_IF_FAIL (index >= 0, ctxt, NULL, "negative index");
1286 : 30 : int num_params = func->get_params ().length ();
1287 : 30 : RETURN_NULL_IF_FAIL_PRINTF3 (index < num_params,
1288 : : ctxt, NULL,
1289 : : "index of %d is too large (%s has %d params)",
1290 : : index,
1291 : : func->get_debug_string (),
1292 : : num_params);
1293 : :
1294 : 30 : return static_cast <gcc_jit_param *> (func->get_param (index));
1295 : 30 : }
1296 : :
1297 : : /* Public entrypoint. See description in libgccjit.h.
1298 : :
1299 : : After error-checking, the real work is done by the
1300 : : gcc::jit::recording::function::get_params method, in
1301 : : jit-recording.h.
1302 : : */
1303 : :
1304 : : size_t
1305 : 15 : gcc_jit_function_get_param_count (gcc_jit_function *func)
1306 : : {
1307 : 15 : RETURN_VAL_IF_FAIL (func, 0, NULL, NULL, "NULL function");
1308 : 15 : gcc::jit::recording::context *ctxt = func->m_ctxt;
1309 : 15 : JIT_LOG_FUNC (ctxt->get_logger ());
1310 : 15 : return func->get_params ().length ();
1311 : 15 : }
1312 : :
1313 : : /* Public entrypoint. See description in libgccjit.h.
1314 : :
1315 : : After error-checking, the real work is done by the
1316 : : gcc::jit::recording::function::get_return_type method, in
1317 : : jit-recording.h. */
1318 : :
1319 : : gcc_jit_type *
1320 : 15 : gcc_jit_function_get_return_type (gcc_jit_function *func)
1321 : : {
1322 : 15 : RETURN_NULL_IF_FAIL (func, NULL, NULL, "NULL function_type");
1323 : 15 : return (gcc_jit_type *)func->get_return_type ();
1324 : : }
1325 : :
1326 : : /* Public entrypoint. See description in libgccjit.h.
1327 : :
1328 : : After error-checking, the real work is done by the
1329 : : gcc::jit::recording::function::dump_to_dot method, in
1330 : : jit-recording.cc. */
1331 : :
1332 : : void
1333 : 0 : gcc_jit_function_dump_to_dot (gcc_jit_function *func,
1334 : : const char *path)
1335 : : {
1336 : 0 : RETURN_IF_FAIL (func, NULL, NULL, "NULL function");
1337 : 0 : gcc::jit::recording::context *ctxt = func->m_ctxt;
1338 : 0 : JIT_LOG_FUNC (ctxt->get_logger ());
1339 : 0 : RETURN_IF_FAIL (path, ctxt, NULL, "NULL path");
1340 : :
1341 : 0 : func->dump_to_dot (path);
1342 : 0 : }
1343 : :
1344 : : /* Public entrypoint. See description in libgccjit.h.
1345 : :
1346 : : After error-checking, the real work is done by the
1347 : : gcc::jit::recording::function::new_block method, in
1348 : : jit-recording.cc. */
1349 : :
1350 : : gcc_jit_block*
1351 : 6761 : gcc_jit_function_new_block (gcc_jit_function *func,
1352 : : const char *name)
1353 : : {
1354 : 6761 : RETURN_NULL_IF_FAIL (func, NULL, NULL, "NULL function");
1355 : 6501 : JIT_LOG_FUNC (func->get_context ()->get_logger ());
1356 : 6501 : RETURN_NULL_IF_FAIL (func->get_kind () != GCC_JIT_FUNCTION_IMPORTED,
1357 : : func->get_context (), NULL,
1358 : : "cannot add block to an imported function");
1359 : : /* name can be NULL. */
1360 : :
1361 : 6279 : return (gcc_jit_block *)func->new_block (name);
1362 : 6501 : }
1363 : :
1364 : : /* Public entrypoint. See description in libgccjit.h.
1365 : :
1366 : : After error-checking, this calls the trivial
1367 : : gcc::jit::recording::memento::as_object method (a block is a
1368 : : memento), in jit-recording.h. */
1369 : :
1370 : : gcc_jit_object *
1371 : 237 : gcc_jit_block_as_object (gcc_jit_block *block)
1372 : : {
1373 : 237 : RETURN_NULL_IF_FAIL (block, NULL, NULL, "NULL block");
1374 : :
1375 : 237 : return static_cast <gcc_jit_object *> (block->as_object ());
1376 : : }
1377 : :
1378 : : /* Public entrypoint. See description in libgccjit.h.
1379 : :
1380 : : After error-checking, the real work is done by the
1381 : : gcc::jit::recording::block::get_function method, in
1382 : : jit-recording.h. */
1383 : :
1384 : : gcc_jit_function *
1385 : 0 : gcc_jit_block_get_function (gcc_jit_block *block)
1386 : : {
1387 : 0 : RETURN_NULL_IF_FAIL (block, NULL, NULL, "NULL block");
1388 : :
1389 : 0 : return static_cast <gcc_jit_function *> (block->get_function ());
1390 : : }
1391 : :
1392 : : /* Public entrypoint. See description in libgccjit.h.
1393 : :
1394 : : After error-checking, the real work is done by the
1395 : : gcc::jit::recording::context::new_global method, in
1396 : : jit-recording.cc. */
1397 : :
1398 : : gcc_jit_lvalue *
1399 : 2555 : gcc_jit_context_new_global (gcc_jit_context *ctxt,
1400 : : gcc_jit_location *loc,
1401 : : enum gcc_jit_global_kind kind,
1402 : : gcc_jit_type *type,
1403 : : const char *name)
1404 : : {
1405 : 2555 : RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
1406 : 2555 : JIT_LOG_FUNC (ctxt->get_logger ());
1407 : : /* LOC can be NULL. */
1408 : 2555 : RETURN_NULL_IF_FAIL_PRINTF1 (
1409 : : ((kind >= GCC_JIT_GLOBAL_EXPORTED)
1410 : : && (kind <= GCC_JIT_GLOBAL_IMPORTED)),
1411 : : ctxt, loc,
1412 : : "unrecognized value for enum gcc_jit_global_kind: %i",
1413 : : kind);
1414 : 2555 : RETURN_NULL_IF_FAIL (type, ctxt, loc, "NULL type");
1415 : 2503 : RETURN_NULL_IF_FAIL (name, ctxt, loc, "NULL name");
1416 : 2503 : RETURN_NULL_IF_FAIL_PRINTF2 (
1417 : : type->has_known_size (),
1418 : : ctxt, loc,
1419 : : "unknown size for global \"%s\" (type: %s)",
1420 : : name,
1421 : : type->get_debug_string ());
1422 : 2498 : RETURN_NULL_IF_FAIL_PRINTF1 (
1423 : : !type->is_void (),
1424 : : ctxt, loc,
1425 : : "void type for global \"%s\"",
1426 : : name);
1427 : :
1428 : 2439 : return (gcc_jit_lvalue *)ctxt->new_global (loc, kind, type, name);
1429 : 2555 : }
1430 : :
1431 : : extern gcc_jit_rvalue *
1432 : 365 : gcc_jit_context_new_struct_constructor (gcc_jit_context *ctxt,
1433 : : gcc_jit_location *loc,
1434 : : gcc_jit_type *type,
1435 : : size_t num_values,
1436 : : gcc_jit_field **fields,
1437 : : gcc_jit_rvalue **values)
1438 : : {
1439 : 365 : using namespace gcc::jit::recording;
1440 : :
1441 : 365 : RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
1442 : 365 : JIT_LOG_FUNC (ctxt->get_logger ());
1443 : 365 : RETURN_NULL_IF_FAIL (type, ctxt, loc, "NULL type");
1444 : :
1445 : 365 : RETURN_NULL_IF_FAIL_PRINTF1 (type->is_struct (),
1446 : : ctxt, loc,
1447 : : "constructor type is not a struct: %s",
1448 : : type->get_debug_string ());
1449 : :
1450 : 365 : compound_type *ct = reinterpret_cast<compound_type *>(type);
1451 : 365 : gcc::jit::recording::fields *fields_struct = ct->get_fields ();
1452 : 365 : size_t n_fields = fields_struct->length ();
1453 : :
1454 : 365 : RETURN_NULL_IF_FAIL_PRINTF1 (ct->has_known_size (),
1455 : : ctxt, loc,
1456 : : "struct can't be opaque: %s",
1457 : : type->get_debug_string ());
1458 : 365 : RETURN_NULL_IF_FAIL_PRINTF1 (n_fields,
1459 : : ctxt, loc,
1460 : : "no fields in struct: %s",
1461 : : type->get_debug_string ());
1462 : :
1463 : : /* If there is no array input we just short circuit to zero the struct. */
1464 : 365 : if (!num_values)
1465 : 30 : return (gcc_jit_rvalue *)ctxt->new_ctor (loc, type, 0, NULL, NULL);
1466 : :
1467 : 335 : RETURN_NULL_IF_FAIL_PRINTF3 (n_fields >= num_values,
1468 : : ctxt, loc,
1469 : : "more values in constructor (n=%zu) than fields"
1470 : : " in target %s (n=%zu)",
1471 : : num_values,
1472 : : type->get_debug_string (),
1473 : : n_fields);
1474 : :
1475 : : /* It is OK if fields are null here, indicating definiton order,
1476 : : but there has to be a values array. */
1477 : 330 : RETURN_NULL_IF_FAIL (values,
1478 : : ctxt, loc,
1479 : : "'values' NULL with non-zero 'num_values'");
1480 : :
1481 : : size_t idx = 0; /* Runner index for fields in the type object. */
1482 : :
1483 : 895 : for (size_t i = 0; i < num_values; i++)
1484 : : {
1485 : 580 : gcc::jit::recording::rvalue *rv = values[i];
1486 : :
1487 : : /* rv kan be NULL, which would indicate zero init for the field. */
1488 : 580 : gcc::jit::recording::type *rv_type = rv ? rv->get_type () : nullptr;
1489 : :
1490 : : /* If fields are specified we need to check that they are in
1491 : : definition order. */
1492 : 580 : if (fields)
1493 : : {
1494 : 365 : gcc::jit::recording::field *f = fields[i];
1495 : :
1496 : 365 : RETURN_NULL_IF_FAIL_PRINTF1 (
1497 : : f,
1498 : : ctxt, loc,
1499 : : "NULL field in 'fields', at index %zu", i);
1500 : :
1501 : 365 : RETURN_NULL_IF_FAIL_PRINTF3 (
1502 : : f->get_container () ==
1503 : : static_cast<gcc::jit::recording::type*>(type),
1504 : : ctxt, loc,
1505 : : "field object at index %zu (%s), was not used when creating "
1506 : : "the %s",
1507 : : i,
1508 : : f->get_debug_string (),
1509 : : type->get_debug_string ());
1510 : :
1511 : : /* Fields in the constructor need to be in struct definition
1512 : : order, but there can be gaps. */
1513 : : size_t j;
1514 : 565 : for (j = idx; j < n_fields; j++)
1515 : : {
1516 : 565 : field *fs = fields_struct->get_field (j);
1517 : 565 : if (fs == f)
1518 : : {
1519 : : idx = j; /* Advance runner index for next iteration. */
1520 : : break;
1521 : : }
1522 : : }
1523 : :
1524 : 360 : RETURN_NULL_IF_FAIL_PRINTF3 (
1525 : : j != n_fields,
1526 : : ctxt, loc,
1527 : : "field at index %zu in 'fields' is not in definition order "
1528 : : "(struct: %s) (ctor field: %s)",
1529 : : i,
1530 : : type->get_debug_string (),
1531 : : f->get_debug_string ());
1532 : :
1533 : : /* Check that the specified field has the same type as the
1534 : : value, unless the value is null (a zero value init). */
1535 : 360 : RETURN_NULL_IF_FAIL_PRINTF5 (
1536 : : !rv || gcc::jit::types_kinda_same (rv_type,
1537 : : f->get_type ()),
1538 : : ctxt, loc,
1539 : : "value and field not the same unqualified type, at index %zu"
1540 : : " (%s.%s: %s)(value type: %s)",
1541 : : i,
1542 : : type->get_debug_string (),
1543 : : f->get_debug_string (),
1544 : : f->get_type ()->get_debug_string (),
1545 : : rv_type->get_debug_string ());
1546 : : }
1547 : :
1548 : : /* If no fields are specified, check that the value has the same type
1549 : : as the field in the definition of the struct. */
1550 : 570 : if (rv && !fields)
1551 : : {
1552 : 170 : RETURN_NULL_IF_FAIL_PRINTF5 (
1553 : : gcc::jit::types_kinda_same (rv_type,
1554 : : fields_struct->
1555 : : get_field (i)->get_type ()),
1556 : : ctxt, loc,
1557 : : "value and field not the same unqualified type, at index %zu"
1558 : : " (%s.%s: %s)(value type: %s)",
1559 : : i,
1560 : : type->get_debug_string (),
1561 : : fields_struct->get_field (i)->get_debug_string (),
1562 : : fields_struct->get_field (i)->get_type ()->get_debug_string (),
1563 : : rv_type->get_debug_string ());
1564 : : }
1565 : :
1566 : 565 : if (rv)
1567 : : {
1568 : 465 : RETURN_NULL_IF_FAIL_PRINTF1 (
1569 : : !rv_type->is_void (),
1570 : : ctxt, loc,
1571 : : "can't construct the void type, at index %zu", i);
1572 : : }
1573 : : }
1574 : :
1575 : 315 : return (gcc_jit_rvalue *)ctxt->new_ctor (
1576 : : loc,
1577 : : type,
1578 : : num_values,
1579 : : reinterpret_cast<gcc::jit::recording::field**>(fields),
1580 : 315 : reinterpret_cast<gcc::jit::recording::rvalue**>(values));
1581 : 365 : }
1582 : :
1583 : : extern gcc_jit_rvalue *
1584 : 80 : gcc_jit_context_new_union_constructor (gcc_jit_context *ctxt,
1585 : : gcc_jit_location *loc,
1586 : : gcc_jit_type *type,
1587 : : gcc_jit_field *field,
1588 : : gcc_jit_rvalue *value)
1589 : : {
1590 : 80 : using namespace gcc::jit::recording;
1591 : :
1592 : 80 : RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
1593 : 80 : JIT_LOG_FUNC (ctxt->get_logger ());
1594 : 80 : RETURN_NULL_IF_FAIL (type, ctxt, loc, "NULL type");
1595 : :
1596 : 80 : RETURN_NULL_IF_FAIL_PRINTF1 (type->is_union (),
1597 : : ctxt, loc,
1598 : : "constructor type is not an union: %s",
1599 : : type->get_debug_string ());
1600 : :
1601 : 80 : compound_type *ct = reinterpret_cast<compound_type *>(type);
1602 : 80 : gcc::jit::recording::fields *fields_union = ct->get_fields ();
1603 : 80 : size_t n_fields = fields_union->length ();
1604 : :
1605 : 80 : RETURN_NULL_IF_FAIL_PRINTF1 (ct->has_known_size (),
1606 : : ctxt, loc,
1607 : : "union can't be opaque: %s",
1608 : : type->get_debug_string ());
1609 : 80 : RETURN_NULL_IF_FAIL_PRINTF1 (n_fields,
1610 : : ctxt, loc,
1611 : : "no fields in union: %s",
1612 : : type->get_debug_string ());
1613 : :
1614 : : /* If value is NULL we are just supposed to zero the whole union. */
1615 : 80 : if (!value)
1616 : 15 : return (gcc_jit_rvalue *)ctxt->new_ctor (loc, type, 0, NULL, NULL);
1617 : :
1618 : 65 : gcc::jit::recording::type *rv_type = value->get_type ();
1619 : :
1620 : 65 : RETURN_NULL_IF_FAIL (
1621 : : !rv_type->is_void (),
1622 : : ctxt, loc,
1623 : : "can't construct the void type");
1624 : :
1625 : 65 : if (field)
1626 : : {
1627 : 50 : RETURN_NULL_IF_FAIL_PRINTF2 (
1628 : : field->get_container () ==
1629 : : static_cast<gcc::jit::recording::type*>(type),
1630 : : ctxt, loc,
1631 : : "field object (%s) was not used when creating "
1632 : : "the type %s",
1633 : : field->get_debug_string (),
1634 : : type->get_debug_string ());
1635 : :
1636 : 45 : RETURN_NULL_IF_FAIL_PRINTF4 (
1637 : : gcc::jit::types_kinda_same (rv_type,
1638 : : field->get_type ()),
1639 : : ctxt, loc,
1640 : : "value and field are not the same unqualified type"
1641 : : " (%s.%s: %s)(value type: %s)",
1642 : : type->get_debug_string (),
1643 : : field->get_debug_string (),
1644 : : field->get_type ()->get_debug_string (),
1645 : : rv_type->get_debug_string ());
1646 : : }
1647 : : /* If no field is specified, check that the value has the same type
1648 : : as the first field in the definition of the union. */
1649 : 60 : if (!field)
1650 : 15 : RETURN_NULL_IF_FAIL_PRINTF2 (
1651 : : gcc::jit::types_kinda_same (rv_type,
1652 : : fields_union->
1653 : : get_field (0)->get_type ()),
1654 : : ctxt, loc,
1655 : : "value and first union field not the same unqualified type"
1656 : : " (field type: %s)(value type: %s)",
1657 : : fields_union->get_field (0)->get_type ()->get_debug_string (),
1658 : : rv_type->get_debug_string ());
1659 : :
1660 : :
1661 : 60 : return (gcc_jit_rvalue *)ctxt->new_ctor (
1662 : : loc,
1663 : : type,
1664 : : 1,
1665 : : /* A NULL fields array tells new_ctor to take fields from the type obj. */
1666 : 60 : reinterpret_cast<gcc::jit::recording::field**>(field ? &field : NULL),
1667 : 60 : reinterpret_cast<gcc::jit::recording::rvalue**>(&value));
1668 : 80 : }
1669 : :
1670 : : extern gcc_jit_rvalue *
1671 : 250 : gcc_jit_context_new_array_constructor (gcc_jit_context *ctxt,
1672 : : gcc_jit_location *loc,
1673 : : gcc_jit_type *type,
1674 : : size_t num_values,
1675 : : gcc_jit_rvalue **values)
1676 : : {
1677 : 250 : using namespace gcc::jit::recording;
1678 : :
1679 : 250 : RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
1680 : 250 : JIT_LOG_FUNC (ctxt->get_logger ());
1681 : 250 : RETURN_NULL_IF_FAIL (type, ctxt, loc, "NULL type");
1682 : :
1683 : 250 : RETURN_NULL_IF_FAIL (type->is_array () != NULL,
1684 : : ctxt, loc,
1685 : : "constructor type not an array");
1686 : :
1687 : 250 : if (!num_values)
1688 : : values = NULL;
1689 : :
1690 : 235 : if (num_values)
1691 : : {
1692 : 235 : RETURN_NULL_IF_FAIL (
1693 : : values,
1694 : : ctxt, loc,
1695 : : "'values' NULL with non-zero 'num_values'");
1696 : :
1697 : 235 : gcc::jit::recording::array_type *arr_type =
1698 : : reinterpret_cast<gcc::jit::recording::array_type*>(type);
1699 : 235 : size_t n_el = arr_type->num_elements ();
1700 : :
1701 : 235 : RETURN_NULL_IF_FAIL_PRINTF2 (
1702 : : n_el >= num_values,
1703 : : ctxt, loc,
1704 : : "array constructor has more values than the array type's length"
1705 : : " (array type length: %zu, constructor length: %zu)",
1706 : : n_el,
1707 : : num_values);
1708 : :
1709 : : /* For arrays, all values need to be the same base type. */
1710 : 275 : gcc::jit::recording::type *type0 = NULL;
1711 : : size_t i = 0;
1712 : : /* Find first non-null value. */
1713 : 275 : for (;i < num_values; i++)
1714 : : {
1715 : 275 : if (values[i])
1716 : : break;
1717 : : }
1718 : :
1719 : 230 : if (i < num_values) /* All values might be null and i == num_values. */
1720 : 230 : type0 = values[i]->get_type ();
1721 : :
1722 : : /* If we got a type0, check that all other values have
1723 : : the same type. */
1724 : 925 : for (; i < num_values; i++)
1725 : : {
1726 : 695 : if (values[i])
1727 : 665 : RETURN_NULL_IF_FAIL_PRINTF3 (
1728 : : gcc::jit::types_kinda_same (type0,
1729 : : values[i]->get_type ()),
1730 : : ctxt, loc,
1731 : : "value type at index %zu differ from first value type"
1732 : : " (first type: %s)(different type: %s)",
1733 : : i,
1734 : : type0->get_debug_string (),
1735 : : values[i]->get_type ()->get_debug_string ());
1736 : : }
1737 : :
1738 : : /* Compare type0 with the element type specified in the
1739 : : type of the array. */
1740 : 230 : if (type0)
1741 : : {
1742 : 230 : gcc::jit::recording::type *el_type =
1743 : 230 : type->is_array ();
1744 : :
1745 : 230 : RETURN_NULL_IF_FAIL_PRINTF2 (
1746 : : gcc::jit::types_kinda_same (type0, el_type),
1747 : : ctxt, loc,
1748 : : "array element value types differ from types in 'values'"
1749 : : " (element type: %s)('values' type: %s)",
1750 : : el_type->get_debug_string (),
1751 : : type0->get_debug_string ());
1752 : : }
1753 : : }
1754 : :
1755 : 240 : return (gcc_jit_rvalue *)ctxt->new_ctor (
1756 : : loc,
1757 : : type,
1758 : : num_values,
1759 : : NULL,
1760 : 240 : reinterpret_cast<gcc::jit::recording::rvalue**>(values));
1761 : 250 : }
1762 : :
1763 : : /* Public entrypoint. See description in libgccjit.h. */
1764 : :
1765 : : extern gcc_jit_lvalue *
1766 : 850 : gcc_jit_global_set_initializer_rvalue (gcc_jit_lvalue *global,
1767 : : gcc_jit_rvalue *init_rvalue)
1768 : : {
1769 : 850 : RETURN_NULL_IF_FAIL (global, NULL, NULL,"NULL global");
1770 : :
1771 : 850 : gcc::jit::recording::context *ctxt = global->get_context ();
1772 : 850 : RETURN_NULL_IF_FAIL (ctxt, NULL, NULL,"NULL context");
1773 : 850 : JIT_LOG_FUNC (ctxt->get_logger ());
1774 : 850 : RETURN_NULL_IF_FAIL (init_rvalue, ctxt, NULL,"NULL init_rvalue");
1775 : :
1776 : 850 : RETURN_NULL_IF_FAIL_PRINTF1 (global->is_global (),
1777 : : ctxt, NULL,
1778 : : "lvalue \"%s\" not a global",
1779 : : global->get_debug_string ());
1780 : :
1781 : 850 : gcc::jit::recording::global *gbl =
1782 : : reinterpret_cast<gcc::jit::recording::global *> (global);
1783 : :
1784 : 850 : RETURN_NULL_IF_FAIL_PRINTF1 (gbl->get_kind () !=
1785 : : GCC_JIT_GLOBAL_IMPORTED,
1786 : : ctxt, NULL,
1787 : : "can't initialize \"%s\", it is imported",
1788 : : global->get_debug_string ());
1789 : :
1790 : 850 : RETURN_NULL_IF_FAIL_PRINTF4 (gcc::jit::types_kinda_same (
1791 : : global->get_type (),
1792 : : init_rvalue->get_type ()),
1793 : : ctxt, NULL,
1794 : : "mismatching types:"
1795 : : " initializing %s (type: %s) with %s (type: %s)",
1796 : : global->get_debug_string (),
1797 : : global->get_type ()->get_debug_string (),
1798 : : init_rvalue->get_debug_string (),
1799 : : init_rvalue->get_type ()->get_debug_string ());
1800 : :
1801 : : /* Check that there are no initializers set for the global yet. */
1802 : 850 : RETURN_NULL_IF_FAIL_PRINTF1 (!gbl->test_flags_anyof (
1803 : : gcc::jit::GLOBAL_VAR_FLAGS_WILL_BE_RVAL_INIT |
1804 : : gcc::jit::GLOBAL_VAR_FLAGS_WILL_BE_BLOB_INIT),
1805 : : ctxt, NULL,
1806 : : "global variable already initialized: %s",
1807 : : global->get_debug_string ());
1808 : :
1809 : : /* The global need to know during playback that it will be
1810 : : initialized. */
1811 : 845 : gbl->set_flags (gcc::jit::GLOBAL_VAR_FLAGS_WILL_BE_RVAL_INIT);
1812 : :
1813 : 845 : ctxt->new_global_init_rvalue (global, init_rvalue);
1814 : :
1815 : 845 : return global;
1816 : 850 : }
1817 : :
1818 : : /* Public entrypoint. See description in libgccjit.h.
1819 : :
1820 : : After error-checking, the real work is done by the
1821 : : gcc::jit::recording::global::set_initializer method, in
1822 : : jit-recording.cc. */
1823 : :
1824 : : extern gcc_jit_lvalue *
1825 : 15 : gcc_jit_global_set_initializer (gcc_jit_lvalue *global,
1826 : : const void *blob,
1827 : : size_t num_bytes)
1828 : : {
1829 : 15 : RETURN_NULL_IF_FAIL (global, NULL, NULL, "NULL global");
1830 : 15 : RETURN_NULL_IF_FAIL (blob, NULL, NULL, "NULL blob");
1831 : 15 : RETURN_NULL_IF_FAIL_PRINTF1 (global->is_global (), NULL, NULL,
1832 : : "lvalue \"%s\" not a global",
1833 : : global->get_debug_string ());
1834 : :
1835 : 15 : gcc::jit::recording::type *lval_type = global->get_type ();
1836 : 15 : RETURN_NULL_IF_FAIL_PRINTF1 (lval_type->is_array (), NULL, NULL,
1837 : : "global \"%s\" is not an array",
1838 : : global->get_debug_string ());
1839 : 15 : RETURN_NULL_IF_FAIL_PRINTF1 (lval_type->dereference ()->is_int (), NULL, NULL,
1840 : : "global \"%s\" is not an array of integral type",
1841 : : global->get_debug_string ());
1842 : 15 : size_t lvalue_size =
1843 : 15 : lval_type->dereference ()->get_size ()
1844 : 15 : * static_cast <gcc::jit::recording::array_type *> (lval_type)->num_elements ();
1845 : 15 : RETURN_NULL_IF_FAIL_PRINTF3 (
1846 : : lvalue_size == num_bytes, NULL, NULL,
1847 : : "mismatching sizes:"
1848 : : " global \"%s\" has size %zu whereas initializer has size %zu",
1849 : : global->get_debug_string (), lvalue_size, num_bytes);
1850 : :
1851 : : /* Check that the rvalue initializer is not set for this global.
1852 : : Note that we do not check if this blob type initializer is
1853 : : already set, since that check was not present when the entrypoint
1854 : : was initially written. */
1855 : 15 : gcc::jit::recording::global *gbl =
1856 : : reinterpret_cast<gcc::jit::recording::global *> (global);
1857 : 15 : RETURN_NULL_IF_FAIL_PRINTF1 (!gbl->test_flags_anyof (
1858 : : gcc::jit::GLOBAL_VAR_FLAGS_WILL_BE_RVAL_INIT),
1859 : : NULL, NULL,
1860 : : "global variable already initialized: %s",
1861 : : global->get_debug_string ());
1862 : :
1863 : 15 : gbl->set_initializer (blob, num_bytes);
1864 : : /* The global need to know during playback that it will be
1865 : : initialized. */
1866 : 15 : gbl->set_flags (gcc::jit::GLOBAL_VAR_FLAGS_WILL_BE_BLOB_INIT);
1867 : :
1868 : 15 : return global;
1869 : : }
1870 : :
1871 : : /* Public entrypoint. See description in libgccjit.h.
1872 : :
1873 : : After error-checking, this calls the trivial
1874 : : gcc::jit::recording::memento::as_object method (an lvalue is a
1875 : : memento), in jit-recording.h. */
1876 : :
1877 : : gcc_jit_object *
1878 : 30 : gcc_jit_lvalue_as_object (gcc_jit_lvalue *lvalue)
1879 : : {
1880 : 30 : RETURN_NULL_IF_FAIL (lvalue, NULL, NULL, "NULL lvalue");
1881 : :
1882 : 30 : return static_cast <gcc_jit_object *> (lvalue->as_object ());
1883 : : }
1884 : :
1885 : : /* Public entrypoint. See description in libgccjit.h.
1886 : :
1887 : : After error-checking, this calls the trivial
1888 : : gcc::jit::recording::lvalue::as_rvalue method in jit-recording.h. */
1889 : :
1890 : : gcc_jit_rvalue *
1891 : 9462 : gcc_jit_lvalue_as_rvalue (gcc_jit_lvalue *lvalue)
1892 : : {
1893 : 9462 : RETURN_NULL_IF_FAIL (lvalue, NULL, NULL, "NULL lvalue");
1894 : :
1895 : 8913 : return (gcc_jit_rvalue *)lvalue->as_rvalue ();
1896 : : }
1897 : :
1898 : : /* Public entrypoint. See description in libgccjit.h.
1899 : :
1900 : : After error-checking, this calls the trivial
1901 : : gcc::jit::recording::memento::as_object method (an rvalue is a
1902 : : memento), in jit-recording.h. */
1903 : :
1904 : : gcc_jit_object *
1905 : 2116 : gcc_jit_rvalue_as_object (gcc_jit_rvalue *rvalue)
1906 : : {
1907 : 2116 : RETURN_NULL_IF_FAIL (rvalue, NULL, NULL, "NULL rvalue");
1908 : :
1909 : 2116 : return static_cast <gcc_jit_object *> (rvalue->as_object ());
1910 : : }
1911 : :
1912 : : /* Public entrypoint. See description in libgccjit.h.
1913 : :
1914 : : After error-checking, the real work is done by the
1915 : : gcc::jit::recording::rvalue::get_type method, in
1916 : : jit-recording.h. */
1917 : :
1918 : : gcc_jit_type *
1919 : 366 : gcc_jit_rvalue_get_type (gcc_jit_rvalue *rvalue)
1920 : : {
1921 : 366 : RETURN_NULL_IF_FAIL (rvalue, NULL, NULL, "NULL rvalue");
1922 : :
1923 : 366 : return static_cast <gcc_jit_type *> (rvalue->get_type ());
1924 : : }
1925 : :
1926 : : /* Verify that NUMERIC_TYPE is non-NULL, and that it is a "numeric"
1927 : : type i.e. it satisfies gcc::jit::type::is_numeric (), such as the
1928 : : result of gcc_jit_context_get_type (GCC_JIT_TYPE_INT). */
1929 : :
1930 : : #define RETURN_NULL_IF_FAIL_NONNULL_NUMERIC_TYPE(CTXT, NUMERIC_TYPE) \
1931 : : JIT_BEGIN_STMT \
1932 : : RETURN_NULL_IF_FAIL (NUMERIC_TYPE, CTXT, NULL, "NULL type"); \
1933 : : RETURN_NULL_IF_FAIL_PRINTF1 ( \
1934 : : NUMERIC_TYPE->is_numeric (), ctxt, NULL, \
1935 : : "not a numeric type: %s", \
1936 : : NUMERIC_TYPE->get_debug_string ()); \
1937 : : JIT_END_STMT
1938 : :
1939 : : /* Public entrypoint. See description in libgccjit.h.
1940 : :
1941 : : After error-checking, the real work is done by the
1942 : : gcc::jit::recording::context::new_rvalue_from_const <int> method in
1943 : : jit-recording.cc. */
1944 : :
1945 : : gcc_jit_rvalue *
1946 : 7603 : gcc_jit_context_new_rvalue_from_int (gcc_jit_context *ctxt,
1947 : : gcc_jit_type *numeric_type,
1948 : : int value)
1949 : : {
1950 : 7603 : RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
1951 : 7603 : JIT_LOG_FUNC (ctxt->get_logger ());
1952 : 7603 : RETURN_NULL_IF_FAIL_NONNULL_NUMERIC_TYPE (ctxt, numeric_type);
1953 : :
1954 : 6983 : return ((gcc_jit_rvalue *)ctxt
1955 : 6983 : ->new_rvalue_from_const <int> (numeric_type, value));
1956 : 7603 : }
1957 : :
1958 : : /* Public entrypoint. See description in libgccjit.h.
1959 : :
1960 : : After error-checking, the real work is done by the
1961 : : gcc::jit::recording::context::new_rvalue_from_const <long> method
1962 : : in jit-recording.cc. */
1963 : :
1964 : : gcc_jit_rvalue *
1965 : 80 : gcc_jit_context_new_rvalue_from_long (gcc_jit_context *ctxt,
1966 : : gcc_jit_type *numeric_type,
1967 : : long value)
1968 : : {
1969 : 80 : RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
1970 : 80 : JIT_LOG_FUNC (ctxt->get_logger ());
1971 : 80 : RETURN_NULL_IF_FAIL_NONNULL_NUMERIC_TYPE (ctxt, numeric_type);
1972 : :
1973 : 80 : return ((gcc_jit_rvalue *)ctxt
1974 : 80 : ->new_rvalue_from_const <long> (numeric_type, value));
1975 : 80 : }
1976 : :
1977 : : /* Public entrypoint. See description in libgccjit.h.
1978 : :
1979 : : This is essentially equivalent to:
1980 : : gcc_jit_context_new_rvalue_from_int (ctxt, numeric_type, 0);
1981 : : albeit with slightly different error messages if an error occurs. */
1982 : :
1983 : : gcc_jit_rvalue *
1984 : 395 : gcc_jit_context_zero (gcc_jit_context *ctxt,
1985 : : gcc_jit_type *numeric_type)
1986 : : {
1987 : 395 : RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
1988 : 395 : JIT_LOG_FUNC (ctxt->get_logger ());
1989 : 395 : RETURN_NULL_IF_FAIL_NONNULL_NUMERIC_TYPE (ctxt, numeric_type);
1990 : :
1991 : 395 : return gcc_jit_context_new_rvalue_from_int (ctxt, numeric_type, 0);
1992 : 395 : }
1993 : :
1994 : : /* Public entrypoint. See description in libgccjit.h.
1995 : :
1996 : : This is essentially equivalent to:
1997 : : gcc_jit_context_new_rvalue_from_int (ctxt, numeric_type, 1);
1998 : : albeit with slightly different error messages if an error occurs. */
1999 : :
2000 : : gcc_jit_rvalue *
2001 : 216 : gcc_jit_context_one (gcc_jit_context *ctxt,
2002 : : gcc_jit_type *numeric_type)
2003 : : {
2004 : 216 : RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
2005 : 216 : JIT_LOG_FUNC (ctxt->get_logger ());
2006 : 216 : RETURN_NULL_IF_FAIL_NONNULL_NUMERIC_TYPE (ctxt, numeric_type);
2007 : :
2008 : 216 : return gcc_jit_context_new_rvalue_from_int (ctxt, numeric_type, 1);
2009 : 216 : }
2010 : :
2011 : : /* Public entrypoint. See description in libgccjit.h.
2012 : :
2013 : : After error-checking, the real work is done by the
2014 : : gcc::jit::recording::context::new_rvalue_from_const <double> method in
2015 : : jit-recording.cc. */
2016 : :
2017 : : gcc_jit_rvalue *
2018 : 145 : gcc_jit_context_new_rvalue_from_double (gcc_jit_context *ctxt,
2019 : : gcc_jit_type *numeric_type,
2020 : : double value)
2021 : : {
2022 : 145 : RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
2023 : 145 : JIT_LOG_FUNC (ctxt->get_logger ());
2024 : 145 : RETURN_NULL_IF_FAIL_NONNULL_NUMERIC_TYPE (ctxt, numeric_type);
2025 : :
2026 : 140 : return ((gcc_jit_rvalue *)ctxt
2027 : 140 : ->new_rvalue_from_const <double> (numeric_type, value));
2028 : 145 : }
2029 : :
2030 : : /* Public entrypoint. See description in libgccjit.h.
2031 : :
2032 : : After error-checking, the real work is done by the
2033 : : gcc::jit::recording::context::new_rvalue_from_const <void *> method
2034 : : in jit-recording.cc. */
2035 : :
2036 : : gcc_jit_rvalue *
2037 : 150 : gcc_jit_context_new_rvalue_from_ptr (gcc_jit_context *ctxt,
2038 : : gcc_jit_type *pointer_type,
2039 : : void *value)
2040 : : {
2041 : 150 : RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
2042 : 150 : JIT_LOG_FUNC (ctxt->get_logger ());
2043 : 150 : RETURN_NULL_IF_FAIL (pointer_type, ctxt, NULL, "NULL type");
2044 : 150 : RETURN_NULL_IF_FAIL_PRINTF1 (
2045 : : pointer_type->is_pointer (),
2046 : : ctxt, NULL,
2047 : : "not a pointer type (type: %s)",
2048 : : pointer_type->get_debug_string ());
2049 : :
2050 : 150 : return ((gcc_jit_rvalue *)ctxt
2051 : 150 : ->new_rvalue_from_const <void *> (pointer_type, value));
2052 : 150 : }
2053 : :
2054 : : /* Public entrypoint. See description in libgccjit.h.
2055 : :
2056 : : This is essentially equivalent to:
2057 : : gcc_jit_context_new_rvalue_from_ptr (ctxt, pointer_type, NULL);
2058 : : albeit with slightly different error messages if an error occurs. */
2059 : :
2060 : : gcc_jit_rvalue *
2061 : 55 : gcc_jit_context_null (gcc_jit_context *ctxt,
2062 : : gcc_jit_type *pointer_type)
2063 : : {
2064 : 55 : RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
2065 : 55 : JIT_LOG_FUNC (ctxt->get_logger ());
2066 : 55 : RETURN_NULL_IF_FAIL (pointer_type, ctxt, NULL, "NULL type");
2067 : 55 : RETURN_NULL_IF_FAIL_PRINTF1 (
2068 : : pointer_type->is_pointer (),
2069 : : ctxt, NULL,
2070 : : "not a pointer type (type: %s)",
2071 : : pointer_type->get_debug_string ());
2072 : :
2073 : 55 : return gcc_jit_context_new_rvalue_from_ptr (ctxt, pointer_type, NULL);
2074 : 55 : }
2075 : :
2076 : : /* Public entrypoint. See description in libgccjit.h.
2077 : :
2078 : : After error-checking, the real work is done by the
2079 : : gcc::jit::recording::context::new_sizeof method in
2080 : : jit-recording.cc. */
2081 : :
2082 : : gcc_jit_rvalue *
2083 : 15 : gcc_jit_context_new_sizeof (gcc_jit_context *ctxt,
2084 : : gcc_jit_type *type)
2085 : : {
2086 : 15 : RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
2087 : 15 : RETURN_NULL_IF_FAIL (type, ctxt, NULL, "NULL type");
2088 : 15 : JIT_LOG_FUNC (ctxt->get_logger ());
2089 : :
2090 : 15 : return ((gcc_jit_rvalue *)ctxt
2091 : 15 : ->new_sizeof (type));
2092 : 15 : }
2093 : :
2094 : : /* Public entrypoint. See description in libgccjit.h.
2095 : :
2096 : : After error-checking, the real work is done by the
2097 : : gcc::jit::recording::context::new_string_literal method in
2098 : : jit-recording.cc. */
2099 : :
2100 : : gcc_jit_rvalue *
2101 : 1958 : gcc_jit_context_new_string_literal (gcc_jit_context *ctxt,
2102 : : const char *value)
2103 : : {
2104 : 1958 : RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
2105 : 1958 : JIT_LOG_FUNC (ctxt->get_logger ());
2106 : 1958 : RETURN_NULL_IF_FAIL (value, ctxt, NULL, "NULL value");
2107 : :
2108 : 1958 : return (gcc_jit_rvalue *)ctxt->new_string_literal (value);
2109 : 1958 : }
2110 : :
2111 : : /* Public entrypoint. See description in libgccjit.h.
2112 : :
2113 : : After error-checking, the real work is done by the
2114 : : gcc::jit::recording::context::new_unary_op method in
2115 : : jit-recording.cc. */
2116 : :
2117 : : gcc_jit_rvalue *
2118 : 138 : gcc_jit_context_new_unary_op (gcc_jit_context *ctxt,
2119 : : gcc_jit_location *loc,
2120 : : enum gcc_jit_unary_op op,
2121 : : gcc_jit_type *result_type,
2122 : : gcc_jit_rvalue *rvalue)
2123 : : {
2124 : 138 : RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
2125 : 138 : JIT_LOG_FUNC (ctxt->get_logger ());
2126 : : /* LOC can be NULL. */
2127 : 138 : RETURN_NULL_IF_FAIL_PRINTF1 (
2128 : : (op >= GCC_JIT_UNARY_OP_MINUS
2129 : : && op <= GCC_JIT_UNARY_OP_ABS),
2130 : : ctxt, loc,
2131 : : "unrecognized value for enum gcc_jit_unary_op: %i",
2132 : : op);
2133 : 133 : RETURN_NULL_IF_FAIL (result_type, ctxt, loc, "NULL result_type");
2134 : 133 : RETURN_NULL_IF_FAIL_PRINTF3 (
2135 : : result_type->is_numeric () || result_type->is_numeric_vector (), ctxt, loc,
2136 : : "gcc_jit_unary_op %s with operand %s "
2137 : : "has non-numeric result_type: %s",
2138 : : gcc::jit::unary_op_reproducer_strings[op],
2139 : : rvalue->get_debug_string (),
2140 : : result_type->get_debug_string ());
2141 : 128 : RETURN_NULL_IF_FAIL (rvalue, ctxt, loc, "NULL rvalue");
2142 : :
2143 : 128 : return (gcc_jit_rvalue *)ctxt->new_unary_op (loc, op, result_type, rvalue);
2144 : 138 : }
2145 : :
2146 : : /* Determine if OP is a valid value for enum gcc_jit_binary_op.
2147 : : For use by both gcc_jit_context_new_binary_op and
2148 : : gcc_jit_block_add_assignment_op. */
2149 : :
2150 : : static bool
2151 : 0 : valid_binary_op_p (enum gcc_jit_binary_op op)
2152 : : {
2153 : 0 : return (op >= GCC_JIT_BINARY_OP_PLUS
2154 : 0 : && op <= GCC_JIT_BINARY_OP_RSHIFT);
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_binary_op method in
2161 : : jit-recording.cc. */
2162 : :
2163 : : gcc_jit_rvalue *
2164 : 3323 : gcc_jit_context_new_binary_op (gcc_jit_context *ctxt,
2165 : : gcc_jit_location *loc,
2166 : : enum gcc_jit_binary_op op,
2167 : : gcc_jit_type *result_type,
2168 : : gcc_jit_rvalue *a, gcc_jit_rvalue *b)
2169 : : {
2170 : 3323 : RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
2171 : 3323 : JIT_LOG_FUNC (ctxt->get_logger ());
2172 : : /* LOC can be NULL. */
2173 : 3323 : RETURN_NULL_IF_FAIL_PRINTF1 (
2174 : : valid_binary_op_p (op),
2175 : : ctxt, loc,
2176 : : "unrecognized value for enum gcc_jit_binary_op: %i",
2177 : : op);
2178 : 3318 : RETURN_NULL_IF_FAIL (result_type, ctxt, loc, "NULL result_type");
2179 : 3318 : RETURN_NULL_IF_FAIL (a, ctxt, loc, "NULL a");
2180 : 3318 : RETURN_NULL_IF_FAIL (b, ctxt, loc, "NULL b");
2181 : 3318 : RETURN_NULL_IF_FAIL_PRINTF4 (
2182 : : compatible_types (a->get_type ()->unqualified (),
2183 : : b->get_type ()->unqualified ()),
2184 : : ctxt, loc,
2185 : : "mismatching types for binary op:"
2186 : : " a: %s (type: %s) b: %s (type: %s)",
2187 : : a->get_debug_string (),
2188 : : a->get_type ()->get_debug_string (),
2189 : : b->get_debug_string (),
2190 : : b->get_type ()->get_debug_string ());
2191 : 3318 : RETURN_NULL_IF_FAIL_PRINTF4 (
2192 : : result_type->is_numeric () || result_type->is_numeric_vector (), ctxt, loc,
2193 : : "gcc_jit_binary_op %s with operands a: %s b: %s "
2194 : : "has non-numeric result_type: %s",
2195 : : gcc::jit::binary_op_reproducer_strings[op],
2196 : : a->get_debug_string (), b->get_debug_string (),
2197 : : result_type->get_debug_string ());
2198 : :
2199 : 3313 : return (gcc_jit_rvalue *)ctxt->new_binary_op (loc, op, result_type, a, b);
2200 : 3323 : }
2201 : :
2202 : : /* Public entrypoint. See description in libgccjit.h.
2203 : :
2204 : : After error-checking, the real work is done by the
2205 : : gcc::jit::recording::context::new_comparison method in
2206 : : jit-recording.cc. */
2207 : :
2208 : : gcc_jit_rvalue *
2209 : 1494 : gcc_jit_context_new_comparison (gcc_jit_context *ctxt,
2210 : : gcc_jit_location *loc,
2211 : : enum gcc_jit_comparison op,
2212 : : gcc_jit_rvalue *a, gcc_jit_rvalue *b)
2213 : : {
2214 : 1494 : RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
2215 : 1494 : JIT_LOG_FUNC (ctxt->get_logger ());
2216 : : /* LOC can be NULL. */
2217 : 1494 : RETURN_NULL_IF_FAIL_PRINTF1 (
2218 : : (op >= GCC_JIT_COMPARISON_EQ
2219 : : && op <= GCC_JIT_COMPARISON_GE),
2220 : : ctxt, loc,
2221 : : "unrecognized value for enum gcc_jit_comparison: %i",
2222 : : op);
2223 : 1494 : RETURN_NULL_IF_FAIL (a, ctxt, loc, "NULL a");
2224 : 1494 : RETURN_NULL_IF_FAIL (b, ctxt, loc, "NULL b");
2225 : 1494 : RETURN_NULL_IF_FAIL_PRINTF4 (
2226 : : a->get_type ()->unqualified () == b->get_type ()->unqualified (),
2227 : : ctxt, loc,
2228 : : "mismatching types for comparison:"
2229 : : " a: %s (type: %s) b: %s (type: %s)",
2230 : : a->get_debug_string (),
2231 : : a->get_type ()->get_debug_string (),
2232 : : b->get_debug_string (),
2233 : : b->get_type ()->get_debug_string ());
2234 : :
2235 : 1494 : return (gcc_jit_rvalue *)ctxt->new_comparison (loc, op, a, b);
2236 : 1494 : }
2237 : :
2238 : : /* Public entrypoint. See description in libgccjit.h.
2239 : :
2240 : : After error-checking, the real work is done by the
2241 : : gcc::jit::recording::context::new_call method in
2242 : : jit-recording.cc. */
2243 : :
2244 : : gcc_jit_rvalue *
2245 : 825 : gcc_jit_context_new_call (gcc_jit_context *ctxt,
2246 : : gcc_jit_location *loc,
2247 : : gcc_jit_function *func,
2248 : : int numargs , gcc_jit_rvalue **args)
2249 : : {
2250 : 825 : RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
2251 : 825 : JIT_LOG_FUNC (ctxt->get_logger ());
2252 : : /* LOC can be NULL. */
2253 : 825 : RETURN_NULL_IF_FAIL (func, ctxt, loc, "NULL function");
2254 : 825 : if (numargs)
2255 : 725 : RETURN_NULL_IF_FAIL (args, ctxt, loc, "NULL args");
2256 : :
2257 : 825 : int min_num_params = func->get_params ().length ();
2258 : 825 : bool is_variadic = func->is_variadic ();
2259 : :
2260 : 825 : RETURN_NULL_IF_FAIL_PRINTF3 (
2261 : : numargs >= min_num_params,
2262 : : ctxt, loc,
2263 : : "not enough arguments to function \"%s\""
2264 : : " (got %i args, expected %i)",
2265 : : func->get_name ()->c_str (),
2266 : : numargs, min_num_params);
2267 : :
2268 : 820 : RETURN_NULL_IF_FAIL_PRINTF3 (
2269 : : (numargs == min_num_params || is_variadic),
2270 : : ctxt, loc,
2271 : : "too many arguments to function \"%s\""
2272 : : " (got %i args, expected %i)",
2273 : : func->get_name ()->c_str (),
2274 : : numargs, min_num_params);
2275 : :
2276 : 1610 : for (int i = 0; i < min_num_params; i++)
2277 : : {
2278 : 810 : gcc::jit::recording::param *param = func->get_param (i);
2279 : 810 : gcc_jit_rvalue *arg = args[i];
2280 : :
2281 : 810 : RETURN_NULL_IF_FAIL_PRINTF4 (
2282 : : arg,
2283 : : ctxt, loc,
2284 : : "NULL argument %i to function \"%s\":"
2285 : : " param %s (type: %s)",
2286 : : i + 1,
2287 : : func->get_name ()->c_str (),
2288 : : param->get_debug_string (),
2289 : : param->get_type ()->get_debug_string ());
2290 : :
2291 : 805 : RETURN_NULL_IF_FAIL_PRINTF6 (
2292 : : compatible_types (param->get_type (),
2293 : : arg->get_type ()),
2294 : : ctxt, loc,
2295 : : "mismatching types for argument %d of function \"%s\":"
2296 : : " assignment to param %s (type: %s) from %s (type: %s)",
2297 : : i + 1,
2298 : : func->get_name ()->c_str (),
2299 : : param->get_debug_string (),
2300 : : param->get_type ()->get_debug_string (),
2301 : : arg->get_debug_string (),
2302 : : arg->get_type ()->get_debug_string ());
2303 : : }
2304 : :
2305 : 800 : return (gcc_jit_rvalue *)ctxt->new_call (loc,
2306 : : func,
2307 : : numargs,
2308 : 800 : (gcc::jit::recording::rvalue **)args);
2309 : 825 : }
2310 : :
2311 : : /* Public entrypoint. See description in libgccjit.h.
2312 : :
2313 : : After error-checking, the real work is done by the
2314 : : gcc::jit::recording::context::new_call_through_ptr method in
2315 : : jit-recording.cc. */
2316 : :
2317 : : gcc_jit_rvalue *
2318 : 40 : gcc_jit_context_new_call_through_ptr (gcc_jit_context *ctxt,
2319 : : gcc_jit_location *loc,
2320 : : gcc_jit_rvalue *fn_ptr,
2321 : : int numargs, gcc_jit_rvalue **args)
2322 : : {
2323 : 40 : RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
2324 : 40 : JIT_LOG_FUNC (ctxt->get_logger ());
2325 : : /* LOC can be NULL. */
2326 : 40 : RETURN_NULL_IF_FAIL (fn_ptr, ctxt, loc, "NULL fn_ptr");
2327 : 40 : if (numargs)
2328 : 35 : RETURN_NULL_IF_FAIL (args, ctxt, loc, "NULL args");
2329 : :
2330 : 40 : gcc::jit::recording::type *ptr_type = fn_ptr->get_type ()->dereference ();
2331 : 40 : RETURN_NULL_IF_FAIL_PRINTF2 (
2332 : : ptr_type, ctxt, loc,
2333 : : "fn_ptr is not a ptr: %s"
2334 : : " type: %s",
2335 : : fn_ptr->get_debug_string (),
2336 : : fn_ptr->get_type ()->get_debug_string ());
2337 : :
2338 : 35 : gcc::jit::recording::function_type *fn_type =
2339 : 35 : ptr_type->dyn_cast_function_type();
2340 : 35 : RETURN_NULL_IF_FAIL_PRINTF2 (
2341 : : fn_type, ctxt, loc,
2342 : : "fn_ptr is not a function ptr: %s"
2343 : : " type: %s",
2344 : : fn_ptr->get_debug_string (),
2345 : : fn_ptr->get_type ()->get_debug_string ());
2346 : :
2347 : 30 : int min_num_params = fn_type->get_param_types ().length ();
2348 : 30 : bool is_variadic = fn_type->is_variadic ();
2349 : :
2350 : 30 : RETURN_NULL_IF_FAIL_PRINTF3 (
2351 : : numargs >= min_num_params,
2352 : : ctxt, loc,
2353 : : "not enough arguments to fn_ptr: %s"
2354 : : " (got %i args, expected %i)",
2355 : : fn_ptr->get_debug_string (),
2356 : : numargs, min_num_params);
2357 : :
2358 : 25 : RETURN_NULL_IF_FAIL_PRINTF3 (
2359 : : (numargs == min_num_params || is_variadic),
2360 : : ctxt, loc,
2361 : : "too many arguments to fn_ptr: %s"
2362 : : " (got %i args, expected %i)",
2363 : : fn_ptr->get_debug_string (),
2364 : : numargs, min_num_params);
2365 : :
2366 : 65 : for (int i = 0; i < min_num_params; i++)
2367 : : {
2368 : 50 : gcc::jit::recording::type *param_type = fn_type->get_param_types ()[i];
2369 : 50 : gcc_jit_rvalue *arg = args[i];
2370 : :
2371 : 50 : RETURN_NULL_IF_FAIL_PRINTF3 (
2372 : : arg,
2373 : : ctxt, loc,
2374 : : "NULL argument %i to fn_ptr: %s"
2375 : : " (type: %s)",
2376 : : i + 1,
2377 : : fn_ptr->get_debug_string (),
2378 : : param_type->get_debug_string ());
2379 : :
2380 : 50 : RETURN_NULL_IF_FAIL_PRINTF6 (
2381 : : compatible_types (param_type,
2382 : : arg->get_type ()),
2383 : : ctxt, loc,
2384 : : "mismatching types for argument %d of fn_ptr: %s:"
2385 : : " assignment to param %d (type: %s) from %s (type: %s)",
2386 : : i + 1,
2387 : : fn_ptr->get_debug_string (),
2388 : : i + 1,
2389 : : param_type->get_debug_string (),
2390 : : arg->get_debug_string (),
2391 : : arg->get_type ()->get_debug_string ());
2392 : : }
2393 : :
2394 : 15 : return (gcc_jit_rvalue *)(
2395 : 15 : ctxt->new_call_through_ptr (loc,
2396 : : fn_ptr,
2397 : : numargs,
2398 : 15 : (gcc::jit::recording::rvalue **)args));
2399 : 40 : }
2400 : :
2401 : : /* Helper function for determining if we can cast an rvalue from SRC_TYPE
2402 : : to DST_TYPE, for use by gcc_jit_context_new_cast.
2403 : :
2404 : : We only permit these kinds of cast:
2405 : :
2406 : : int <-> float
2407 : : int <-> bool
2408 : : P* <-> Q* for pointer types P and Q. */
2409 : :
2410 : : static bool
2411 : 374 : is_valid_cast (gcc::jit::recording::type *src_type,
2412 : : gcc_jit_type *dst_type)
2413 : : {
2414 : 374 : bool src_is_int = src_type->is_int ();
2415 : 374 : bool dst_is_int = dst_type->is_int ();
2416 : 374 : bool src_is_float = src_type->is_float ();
2417 : 374 : bool dst_is_float = dst_type->is_float ();
2418 : 374 : bool src_is_bool = src_type->is_bool ();
2419 : 374 : bool dst_is_bool = dst_type->is_bool ();
2420 : :
2421 : 374 : if (src_is_int)
2422 : 140 : if (dst_is_int || dst_is_float || dst_is_bool)
2423 : : return true;
2424 : :
2425 : 234 : if (src_is_float)
2426 : 15 : if (dst_is_int || dst_is_float)
2427 : : return true;
2428 : :
2429 : 219 : if (src_is_bool)
2430 : 34 : if (dst_is_int || dst_is_bool)
2431 : : return true;
2432 : :
2433 : : /* Permit casts between pointer types. */
2434 : 185 : gcc::jit::recording::type *deref_src_type = src_type->is_pointer ();
2435 : 185 : gcc::jit::recording::type *deref_dst_type = dst_type->is_pointer ();
2436 : 185 : if (deref_src_type && deref_dst_type)
2437 : : return true;
2438 : :
2439 : : return false;
2440 : : }
2441 : :
2442 : : /* Public entrypoint. See description in libgccjit.h.
2443 : :
2444 : : After error-checking, the real work is done by the
2445 : : gcc::jit::recording::context::new_cast method in jit-recording.cc. */
2446 : :
2447 : : gcc_jit_rvalue *
2448 : 374 : gcc_jit_context_new_cast (gcc_jit_context *ctxt,
2449 : : gcc_jit_location *loc,
2450 : : gcc_jit_rvalue *rvalue,
2451 : : gcc_jit_type *type)
2452 : : {
2453 : 374 : RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
2454 : 374 : JIT_LOG_FUNC (ctxt->get_logger ());
2455 : : /* LOC can be NULL. */
2456 : 374 : RETURN_NULL_IF_FAIL (rvalue, ctxt, loc, "NULL rvalue");
2457 : 374 : RETURN_NULL_IF_FAIL (type, ctxt, loc, "NULL type");
2458 : 374 : RETURN_NULL_IF_FAIL_PRINTF3 (
2459 : : is_valid_cast (rvalue->get_type (), type),
2460 : : ctxt, loc,
2461 : : "cannot cast %s from type: %s to type: %s",
2462 : : rvalue->get_debug_string (),
2463 : : rvalue->get_type ()->get_debug_string (),
2464 : : type->get_debug_string ());
2465 : :
2466 : 364 : return static_cast <gcc_jit_rvalue *> (ctxt->new_cast (loc, rvalue, type));
2467 : 374 : }
2468 : :
2469 : : /* Public entrypoint. See description in libgccjit.h.
2470 : :
2471 : : After error-checking, the real work is done by the
2472 : : gcc::jit::recording::context::new_bitcast method in jit-recording.c. */
2473 : :
2474 : : gcc_jit_rvalue *
2475 : 25 : gcc_jit_context_new_bitcast (gcc_jit_context *ctxt,
2476 : : gcc_jit_location *loc,
2477 : : gcc_jit_rvalue *rvalue,
2478 : : gcc_jit_type *type)
2479 : : {
2480 : 25 : RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
2481 : 25 : JIT_LOG_FUNC (ctxt->get_logger ());
2482 : : /* LOC can be NULL. */
2483 : 25 : RETURN_NULL_IF_FAIL (rvalue, ctxt, loc, "NULL rvalue");
2484 : 25 : RETURN_NULL_IF_FAIL (type, ctxt, loc, "NULL type");
2485 : : /* We cannot check if the size of rvalue matches the size of type here, so
2486 : : we'll do it at playback. */
2487 : :
2488 : 25 : return static_cast <gcc_jit_rvalue *> (ctxt->new_bitcast (loc, rvalue, type));
2489 : 25 : }
2490 : :
2491 : : /* Public entrypoint. See description in libgccjit.h.
2492 : :
2493 : : After error-checking, the real work is done by the
2494 : : gcc::jit::recording::context::new_array_access method in
2495 : : jit-recording.cc. */
2496 : :
2497 : : extern gcc_jit_lvalue *
2498 : 464 : gcc_jit_context_new_array_access (gcc_jit_context *ctxt,
2499 : : gcc_jit_location *loc,
2500 : : gcc_jit_rvalue *ptr,
2501 : : gcc_jit_rvalue *index)
2502 : : {
2503 : 464 : RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
2504 : 464 : JIT_LOG_FUNC (ctxt->get_logger ());
2505 : : /* LOC can be NULL. */
2506 : 464 : RETURN_NULL_IF_FAIL (ptr, ctxt, loc, "NULL ptr");
2507 : 464 : RETURN_NULL_IF_FAIL (index, ctxt, loc, "NULL index");
2508 : 464 : RETURN_NULL_IF_FAIL_PRINTF2 (
2509 : : ptr->get_type ()->dereference (),
2510 : : ctxt, loc,
2511 : : "ptr: %s (type: %s) is not a pointer or array",
2512 : : ptr->get_debug_string (),
2513 : : ptr->get_type ()->get_debug_string ());
2514 : 464 : RETURN_NULL_IF_FAIL_PRINTF2 (
2515 : : index->get_type ()->is_numeric (),
2516 : : ctxt, loc,
2517 : : "index: %s (type: %s) is not of numeric type",
2518 : : index->get_debug_string (),
2519 : : index->get_type ()->get_debug_string ());
2520 : :
2521 : 459 : return (gcc_jit_lvalue *)ctxt->new_array_access (loc, ptr, index);
2522 : 464 : }
2523 : :
2524 : : /* Public entrypoint. See description in libgccjit.h.
2525 : :
2526 : : After error-checking, the real work is done by the
2527 : : gcc::jit::recording::memento::get_context method in
2528 : : jit-recording.h. */
2529 : :
2530 : : gcc_jit_context *
2531 : 132 : gcc_jit_object_get_context (gcc_jit_object *obj)
2532 : : {
2533 : 132 : RETURN_NULL_IF_FAIL (obj, NULL, NULL, "NULL object");
2534 : :
2535 : 132 : return static_cast <gcc_jit_context *> (obj->get_context ());
2536 : : }
2537 : :
2538 : : /* Public entrypoint. See description in libgccjit.h.
2539 : :
2540 : : After error-checking, the real work is done by the
2541 : : gcc::jit::recording::memento::get_debug_string method in
2542 : : jit-recording.cc. */
2543 : :
2544 : : const char *
2545 : 1240 : gcc_jit_object_get_debug_string (gcc_jit_object *obj)
2546 : : {
2547 : 1240 : RETURN_NULL_IF_FAIL (obj, NULL, NULL, "NULL object");
2548 : :
2549 : 1240 : return obj->get_debug_string ();
2550 : : }
2551 : :
2552 : : /* Public entrypoint. See description in libgccjit.h.
2553 : :
2554 : : After error-checking, the real work is done by the
2555 : : gcc::jit::recording::lvalue::access_field method in
2556 : : jit-recording.cc. */
2557 : :
2558 : : gcc_jit_lvalue *
2559 : 224 : gcc_jit_lvalue_access_field (gcc_jit_lvalue *struct_,
2560 : : gcc_jit_location *loc,
2561 : : gcc_jit_field *field)
2562 : : {
2563 : 224 : RETURN_NULL_IF_FAIL (struct_, NULL, loc, "NULL struct");
2564 : 224 : gcc::jit::recording::context *ctxt = struct_->m_ctxt;
2565 : 224 : JIT_LOG_FUNC (ctxt->get_logger ());
2566 : : /* LOC can be NULL. */
2567 : 224 : RETURN_NULL_IF_FAIL (field, ctxt, loc, "NULL field");
2568 : 224 : RETURN_NULL_IF_FAIL_PRINTF1 (field->get_container (), field->m_ctxt, loc,
2569 : : "field %s has not been placed in a struct",
2570 : : field->get_debug_string ());
2571 : 224 : gcc::jit::recording::type *underlying_type =
2572 : 224 : struct_->get_type ();
2573 : 224 : RETURN_NULL_IF_FAIL_PRINTF2 (
2574 : : (field->get_container ()->unqualified ()
2575 : : == underlying_type->unqualified ()),
2576 : : struct_->m_ctxt, loc,
2577 : : "%s is not a field of %s",
2578 : : field->get_debug_string (),
2579 : : underlying_type->get_debug_string ());
2580 : :
2581 : 219 : return (gcc_jit_lvalue *)struct_->access_field (loc, field);
2582 : 224 : }
2583 : :
2584 : : /* Public entrypoint. See description in libgccjit.h.
2585 : :
2586 : : After error-checking, the real work is done by the
2587 : : gcc::jit::recording::rvalue::access_field method in
2588 : : jit-recording.cc. */
2589 : :
2590 : : gcc_jit_rvalue *
2591 : 144 : gcc_jit_rvalue_access_field (gcc_jit_rvalue *struct_,
2592 : : gcc_jit_location *loc,
2593 : : gcc_jit_field *field)
2594 : : {
2595 : 144 : RETURN_NULL_IF_FAIL (struct_, NULL, loc, "NULL struct");
2596 : 144 : gcc::jit::recording::context *ctxt = struct_->m_ctxt;
2597 : 144 : JIT_LOG_FUNC (ctxt->get_logger ());
2598 : : /* LOC can be NULL. */
2599 : 144 : RETURN_NULL_IF_FAIL (field, ctxt, loc, "NULL field");
2600 : 144 : RETURN_NULL_IF_FAIL_PRINTF1 (field->get_container (), field->m_ctxt, loc,
2601 : : "field %s has not been placed in a struct",
2602 : : field->get_debug_string ());
2603 : 144 : gcc::jit::recording::type *underlying_type =
2604 : 144 : struct_->get_type ();
2605 : 144 : RETURN_NULL_IF_FAIL_PRINTF2 (
2606 : : (field->get_container ()->unqualified ()
2607 : : == underlying_type->unqualified ()),
2608 : : struct_->m_ctxt, loc,
2609 : : "%s is not a field of %s",
2610 : : field->get_debug_string (),
2611 : : underlying_type->get_debug_string ());
2612 : :
2613 : 139 : return (gcc_jit_rvalue *)struct_->access_field (loc, field);
2614 : 144 : }
2615 : :
2616 : : /* Public entrypoint. See description in libgccjit.h.
2617 : :
2618 : : After error-checking, the real work is done by the
2619 : : gcc::jit::recording::rvalue::deference_field method in
2620 : : jit-recording.cc. */
2621 : :
2622 : : gcc_jit_lvalue *
2623 : 1431 : gcc_jit_rvalue_dereference_field (gcc_jit_rvalue *ptr,
2624 : : gcc_jit_location *loc,
2625 : : gcc_jit_field *field)
2626 : : {
2627 : 1431 : RETURN_NULL_IF_FAIL (ptr, NULL, loc, "NULL ptr");
2628 : 1431 : JIT_LOG_FUNC (ptr->get_context ()->get_logger ());
2629 : : /* LOC can be NULL. */
2630 : 1431 : RETURN_NULL_IF_FAIL (field, NULL, loc, "NULL field");
2631 : 1431 : gcc::jit::recording::type *underlying_type =
2632 : 1431 : ptr->get_type ()->is_pointer ();
2633 : 1431 : RETURN_NULL_IF_FAIL_PRINTF1 (field->get_container (), field->m_ctxt, loc,
2634 : : "field %s has not been placed in a struct",
2635 : : field->get_debug_string ());
2636 : 1431 : RETURN_NULL_IF_FAIL_PRINTF3 (
2637 : : underlying_type,
2638 : : ptr->m_ctxt, loc,
2639 : : "dereference of non-pointer %s (type: %s) when accessing ->%s",
2640 : : ptr->get_debug_string (),
2641 : : ptr->get_type ()->get_debug_string (),
2642 : : field->get_debug_string ());
2643 : 1421 : RETURN_NULL_IF_FAIL_PRINTF2 (
2644 : : (field->get_container ()->unqualified ()
2645 : : == underlying_type->unqualified ()),
2646 : : ptr->m_ctxt, loc,
2647 : : "%s is not a field of %s",
2648 : : field->get_debug_string (),
2649 : : underlying_type->get_debug_string ());
2650 : :
2651 : 1411 : return (gcc_jit_lvalue *)ptr->dereference_field (loc, field);
2652 : 1431 : }
2653 : :
2654 : : /* Public entrypoint. See description in libgccjit.h.
2655 : :
2656 : : After error-checking, the real work is done by the
2657 : : gcc::jit::recording::rvalue::deference method in
2658 : : jit-recording.cc. */
2659 : :
2660 : : gcc_jit_lvalue *
2661 : 694 : gcc_jit_rvalue_dereference (gcc_jit_rvalue *rvalue,
2662 : : gcc_jit_location *loc)
2663 : : {
2664 : 694 : RETURN_NULL_IF_FAIL (rvalue, NULL, loc, "NULL rvalue");
2665 : 694 : JIT_LOG_FUNC (rvalue->get_context ()->get_logger ());
2666 : : /* LOC can be NULL. */
2667 : :
2668 : 694 : gcc::jit::recording::type *underlying_type =
2669 : 694 : rvalue->get_type ()->is_pointer ();
2670 : :
2671 : 694 : RETURN_NULL_IF_FAIL_PRINTF2 (
2672 : : underlying_type,
2673 : : rvalue->m_ctxt, loc,
2674 : : "dereference of non-pointer %s (type: %s)",
2675 : : rvalue->get_debug_string (),
2676 : : rvalue->get_type ()->get_debug_string ());
2677 : :
2678 : 689 : RETURN_NULL_IF_FAIL_PRINTF2 (
2679 : : !underlying_type->is_void (),
2680 : : rvalue->m_ctxt, loc,
2681 : : "dereference of void pointer %s (type: %s)",
2682 : : rvalue->get_debug_string (),
2683 : : rvalue->get_type ()->get_debug_string ());
2684 : :
2685 : 684 : return (gcc_jit_lvalue *)rvalue->dereference (loc);
2686 : 694 : }
2687 : :
2688 : : /* Public entrypoint. See description in libgccjit.h.
2689 : :
2690 : : After error-checking, the real work is done by the
2691 : : gcc::jit::recording::lvalue::get_address method in jit-recording.cc. */
2692 : :
2693 : : gcc_jit_rvalue *
2694 : 508 : gcc_jit_lvalue_get_address (gcc_jit_lvalue *lvalue,
2695 : : gcc_jit_location *loc)
2696 : : {
2697 : 508 : RETURN_NULL_IF_FAIL (lvalue, NULL, loc, "NULL lvalue");
2698 : 508 : JIT_LOG_FUNC (lvalue->get_context ()->get_logger ());
2699 : : /* LOC can be NULL. */
2700 : :
2701 : 508 : return (gcc_jit_rvalue *)lvalue->get_address (loc);
2702 : 508 : }
2703 : :
2704 : : /* Public entrypoint. See description in libgccjit.h.
2705 : :
2706 : : After error-checking, the real work is done by the
2707 : : gcc::jit::recording::lvalue::set_tls_model method in jit-recording.cc. */
2708 : :
2709 : : void
2710 : 15 : gcc_jit_lvalue_set_tls_model (gcc_jit_lvalue *lvalue,
2711 : : enum gcc_jit_tls_model model)
2712 : : {
2713 : 15 : RETURN_IF_FAIL (lvalue, NULL, NULL, "NULL lvalue");
2714 : 15 : JIT_LOG_FUNC (lvalue->get_context ()->get_logger ());
2715 : 15 : RETURN_IF_FAIL_PRINTF1 (lvalue->is_global (), lvalue->get_context (), NULL,
2716 : : "lvalue \"%s\" not a global",
2717 : : lvalue->get_debug_string ());
2718 : :
2719 : 15 : lvalue->set_tls_model (model);
2720 : 15 : }
2721 : :
2722 : : /* Public entrypoint. See description in libgccjit.h.
2723 : :
2724 : : After error-checking, the real work is done by the
2725 : : gcc::jit::recording::lvalue::set_link_section method in jit-recording.cc. */
2726 : :
2727 : : void
2728 : 5 : gcc_jit_lvalue_set_link_section (gcc_jit_lvalue *lvalue,
2729 : : const char *section_name)
2730 : : {
2731 : 5 : RETURN_IF_FAIL (section_name, NULL, NULL, "NULL section_name");
2732 : 5 : lvalue->set_link_section (section_name);
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::lvalue::get_alignment method in jit-recording.cc. */
2739 : :
2740 : : unsigned
2741 : 10 : gcc_jit_lvalue_get_alignment (gcc_jit_lvalue *lvalue)
2742 : : {
2743 : 10 : RETURN_VAL_IF_FAIL (lvalue, 0, NULL, NULL, "NULL lvalue");
2744 : 10 : return lvalue->get_alignment ();
2745 : : }
2746 : :
2747 : : /* Public entrypoint. See description in libgccjit.h.
2748 : :
2749 : : After error-checking, the real work is done by the
2750 : : gcc::jit::recording::lvalue::set_alignment method in jit-recording.cc. */
2751 : :
2752 : : void
2753 : 10 : gcc_jit_lvalue_set_alignment (gcc_jit_lvalue *lvalue,
2754 : : unsigned bytes)
2755 : : {
2756 : 10 : RETURN_IF_FAIL (lvalue, NULL, NULL, "NULL lvalue");
2757 : 10 : RETURN_IF_FAIL ((bytes & (bytes - 1)) == 0, NULL, NULL,
2758 : : "alignment is not a power of 2");
2759 : 10 : lvalue->set_alignment (bytes);
2760 : : }
2761 : :
2762 : : /* Public entrypoint. See description in libgccjit.h.
2763 : :
2764 : : After error-checking, the real work is done by the
2765 : : gcc::jit::recording::lvalue::set_register_name method in jit-recording.cc. */
2766 : :
2767 : : void
2768 : 20 : gcc_jit_lvalue_set_register_name (gcc_jit_lvalue *lvalue,
2769 : : const char *reg_name)
2770 : : {
2771 : 20 : RETURN_IF_FAIL (lvalue, NULL, NULL, "NULL lvalue");
2772 : 20 : RETURN_IF_FAIL (reg_name, NULL, NULL, "NULL reg_name");
2773 : 20 : lvalue->set_register_name (reg_name);
2774 : : }
2775 : :
2776 : : /* Public entrypoint. See description in libgccjit.h.
2777 : :
2778 : : After error-checking, the real work is done by the
2779 : : gcc::jit::recording::function::new_local method in jit-recording.cc. */
2780 : :
2781 : : gcc_jit_lvalue *
2782 : 4986 : gcc_jit_function_new_local (gcc_jit_function *func,
2783 : : gcc_jit_location *loc,
2784 : : gcc_jit_type *type,
2785 : : const char *name)
2786 : : {
2787 : 4986 : RETURN_NULL_IF_FAIL (func, NULL, loc, "NULL function");
2788 : 4056 : gcc::jit::recording::context *ctxt = func->m_ctxt;
2789 : 4056 : JIT_LOG_FUNC (ctxt->get_logger ());
2790 : : /* LOC can be NULL. */
2791 : 4056 : RETURN_NULL_IF_FAIL (func->get_kind () != GCC_JIT_FUNCTION_IMPORTED,
2792 : : ctxt, loc,
2793 : : "Cannot add locals to an imported function");
2794 : 4056 : RETURN_NULL_IF_FAIL (type, ctxt, loc, "NULL type");
2795 : 3992 : RETURN_NULL_IF_FAIL (name, ctxt, loc, "NULL name");
2796 : 3992 : RETURN_NULL_IF_FAIL_PRINTF2 (
2797 : : type->has_known_size (),
2798 : : ctxt, loc,
2799 : : "unknown size for local \"%s\" (type: %s)",
2800 : : name,
2801 : : type->get_debug_string ());
2802 : 3987 : RETURN_NULL_IF_FAIL_PRINTF1 (
2803 : : !type->is_void (),
2804 : : ctxt, loc,
2805 : : "void type for local \"%s\"",
2806 : : name);
2807 : :
2808 : 3890 : return (gcc_jit_lvalue *)func->new_local (loc, type, name);
2809 : 4056 : }
2810 : :
2811 : : /* Public entrypoint. See description in libgccjit.h.
2812 : :
2813 : : After error-checking, the real work is done by the
2814 : : gcc::jit::recording::block::add_eval method in jit-recording.cc. */
2815 : :
2816 : : void
2817 : 3312 : gcc_jit_block_add_eval (gcc_jit_block *block,
2818 : : gcc_jit_location *loc,
2819 : : gcc_jit_rvalue *rvalue)
2820 : : {
2821 : 3556 : RETURN_IF_NOT_VALID_BLOCK (block, loc);
2822 : 2266 : gcc::jit::recording::context *ctxt = block->get_context ();
2823 : 2266 : JIT_LOG_FUNC (ctxt->get_logger ());
2824 : : /* LOC can be NULL. */
2825 : 2266 : RETURN_IF_FAIL (rvalue, ctxt, loc, "NULL rvalue");
2826 : :
2827 : 2022 : gcc::jit::recording::statement *stmt = block->add_eval (loc, rvalue);
2828 : :
2829 : : /* "stmt" should be good enough to be usable in error-messages,
2830 : : but might still not be compilable; perform some more
2831 : : error-checking here. We do this here so that the error messages
2832 : : can contain a stringified version of "stmt", whilst appearing
2833 : : as close as possible to the point of failure. */
2834 : 2022 : rvalue->verify_valid_within_stmt (__func__, stmt);
2835 : 2266 : }
2836 : :
2837 : : /* Public entrypoint. See description in libgccjit.h.
2838 : :
2839 : : After error-checking, the real work is done by the
2840 : : gcc::jit::recording::block::add_assignment method in
2841 : : jit-recording.cc. */
2842 : :
2843 : : void
2844 : 7288 : gcc_jit_block_add_assignment (gcc_jit_block *block,
2845 : : gcc_jit_location *loc,
2846 : : gcc_jit_lvalue *lvalue,
2847 : : gcc_jit_rvalue *rvalue)
2848 : : {
2849 : 9100 : RETURN_IF_NOT_VALID_BLOCK (block, loc);
2850 : 6242 : gcc::jit::recording::context *ctxt = block->get_context ();
2851 : 6242 : JIT_LOG_FUNC (ctxt->get_logger ());
2852 : : /* LOC can be NULL. */
2853 : 6242 : RETURN_IF_FAIL (lvalue, ctxt, loc, "NULL lvalue");
2854 : 6105 : RETURN_IF_FAIL (rvalue, ctxt, loc, "NULL rvalue");
2855 : 5884 : RETURN_IF_FAIL_PRINTF4 (
2856 : : compatible_types (lvalue->get_type (),
2857 : : rvalue->get_type ()),
2858 : : ctxt, loc,
2859 : : "mismatching types:"
2860 : : " assignment to %s (type: %s) from %s (type: %s)",
2861 : : lvalue->get_debug_string (),
2862 : : lvalue->get_type ()->get_debug_string (),
2863 : : rvalue->get_debug_string (),
2864 : : rvalue->get_type ()->get_debug_string ());
2865 : :
2866 : 4430 : gcc::jit::recording::statement *stmt = block->add_assignment (loc, lvalue, rvalue);
2867 : :
2868 : : /* "stmt" should be good enough to be usable in error-messages,
2869 : : but might still not be compilable; perform some more
2870 : : error-checking here. We do this here so that the error messages
2871 : : can contain a stringified version of "stmt", whilst appearing
2872 : : as close as possible to the point of failure. */
2873 : 4430 : lvalue->verify_valid_within_stmt (__func__, stmt);
2874 : 4430 : rvalue->verify_valid_within_stmt (__func__, stmt);
2875 : 6242 : }
2876 : :
2877 : : /* Public entrypoint. See description in libgccjit.h.
2878 : :
2879 : : After error-checking, the real work is done by the
2880 : : gcc::jit::recording::block::add_assignment_op method in
2881 : : jit-recording.cc. */
2882 : :
2883 : : void
2884 : 479 : gcc_jit_block_add_assignment_op (gcc_jit_block *block,
2885 : : gcc_jit_location *loc,
2886 : : gcc_jit_lvalue *lvalue,
2887 : : enum gcc_jit_binary_op op,
2888 : : gcc_jit_rvalue *rvalue)
2889 : : {
2890 : 489 : RETURN_IF_NOT_VALID_BLOCK (block, loc);
2891 : 479 : gcc::jit::recording::context *ctxt = block->get_context ();
2892 : 479 : JIT_LOG_FUNC (ctxt->get_logger ());
2893 : : /* LOC can be NULL. */
2894 : 479 : RETURN_IF_FAIL (lvalue, ctxt, loc, "NULL lvalue");
2895 : 474 : RETURN_IF_FAIL_PRINTF1 (
2896 : : valid_binary_op_p (op),
2897 : : ctxt, loc,
2898 : : "unrecognized value for enum gcc_jit_binary_op: %i",
2899 : : op);
2900 : 474 : RETURN_IF_FAIL (rvalue, ctxt, loc, "NULL rvalue");
2901 : 474 : RETURN_IF_FAIL_PRINTF4 (
2902 : : compatible_types (lvalue->get_type (),
2903 : : rvalue->get_type ()),
2904 : : ctxt, loc,
2905 : : "mismatching types:"
2906 : : " assignment to %s (type: %s) involving %s (type: %s)",
2907 : : lvalue->get_debug_string (),
2908 : : lvalue->get_type ()->get_debug_string (),
2909 : : rvalue->get_debug_string (),
2910 : : rvalue->get_type ()->get_debug_string ());
2911 : :
2912 : 469 : gcc::jit::recording::statement *stmt = block->add_assignment_op (loc, lvalue, op, rvalue);
2913 : :
2914 : : /* "stmt" should be good enough to be usable in error-messages,
2915 : : but might still not be compilable; perform some more
2916 : : error-checking here. We do this here so that the error messages
2917 : : can contain a stringified version of "stmt", whilst appearing
2918 : : as close as possible to the point of failure. */
2919 : 469 : lvalue->verify_valid_within_stmt (__func__, stmt);
2920 : 469 : rvalue->verify_valid_within_stmt (__func__, stmt);
2921 : 479 : }
2922 : :
2923 : : /* Internal helper function for determining if rvalue BOOLVAL is of
2924 : : boolean type. For use by gcc_jit_block_end_with_conditional. */
2925 : :
2926 : : static bool
2927 : 864 : is_bool (gcc_jit_rvalue *boolval)
2928 : : {
2929 : 0 : gcc::jit::recording::type *actual_type = boolval->get_type ();
2930 : 864 : gcc::jit::recording::type *bool_type =
2931 : 864 : boolval->m_ctxt->get_type (GCC_JIT_TYPE_BOOL);
2932 : 864 : return actual_type == bool_type;
2933 : : }
2934 : :
2935 : : /* Public entrypoint. See description in libgccjit.h.
2936 : :
2937 : : After error-checking, the real work is done by the
2938 : : gcc::jit::recording::block::end_with_conditional method in
2939 : : jit-recording.cc. */
2940 : :
2941 : : void
2942 : 864 : gcc_jit_block_end_with_conditional (gcc_jit_block *block,
2943 : : gcc_jit_location *loc,
2944 : : gcc_jit_rvalue *boolval,
2945 : : gcc_jit_block *on_true,
2946 : : gcc_jit_block *on_false)
2947 : : {
2948 : 864 : RETURN_IF_NOT_VALID_BLOCK (block, loc);
2949 : 864 : gcc::jit::recording::context *ctxt = block->get_context ();
2950 : 864 : JIT_LOG_FUNC (ctxt->get_logger ());
2951 : : /* LOC can be NULL. */
2952 : 864 : RETURN_IF_FAIL (boolval, ctxt, loc, "NULL boolval");
2953 : 864 : RETURN_IF_FAIL_PRINTF2 (
2954 : : is_bool (boolval), ctxt, loc,
2955 : : "%s (type: %s) is not of boolean type ",
2956 : : boolval->get_debug_string (),
2957 : : boolval->get_type ()->get_debug_string ());
2958 : 864 : RETURN_IF_FAIL (on_true, ctxt, loc, "NULL on_true");
2959 : 864 : RETURN_IF_FAIL (on_true, ctxt, loc, "NULL on_false");
2960 : 864 : RETURN_IF_FAIL_PRINTF4 (
2961 : : block->get_function () == on_true->get_function (),
2962 : : ctxt, loc,
2963 : : "\"on_true\" block is not in same function:"
2964 : : " source block %s is in function %s"
2965 : : " whereas target block %s is in function %s",
2966 : : block->get_debug_string (),
2967 : : block->get_function ()->get_debug_string (),
2968 : : on_true->get_debug_string (),
2969 : : on_true->get_function ()->get_debug_string ());
2970 : 864 : RETURN_IF_FAIL_PRINTF4 (
2971 : : block->get_function () == on_false->get_function (),
2972 : : ctxt, loc,
2973 : : "\"on_false\" block is not in same function:"
2974 : : " source block %s is in function %s"
2975 : : " whereas target block %s is in function %s",
2976 : : block->get_debug_string (),
2977 : : block->get_function ()->get_debug_string (),
2978 : : on_false->get_debug_string (),
2979 : : on_false->get_function ()->get_debug_string ());
2980 : :
2981 : 864 : gcc::jit::recording::statement *stmt = block->end_with_conditional (loc, boolval, on_true, on_false);
2982 : :
2983 : : /* "stmt" should be good enough to be usable in error-messages,
2984 : : but might still not be compilable; perform some more
2985 : : error-checking here. We do this here so that the error messages
2986 : : can contain a stringified version of "stmt", whilst appearing
2987 : : as close as possible to the point of failure. */
2988 : 864 : boolval->verify_valid_within_stmt (__func__, stmt);
2989 : 864 : }
2990 : :
2991 : : /* Public entrypoint. See description in libgccjit.h.
2992 : :
2993 : : After error-checking, the real work is done by the
2994 : : gcc::jit::recording::block::add_comment method in
2995 : : jit-recording.cc. */
2996 : :
2997 : : void
2998 : 420 : gcc_jit_block_add_comment (gcc_jit_block *block,
2999 : : gcc_jit_location *loc,
3000 : : const char *text)
3001 : : {
3002 : 420 : RETURN_IF_NOT_VALID_BLOCK (block, loc);
3003 : 420 : gcc::jit::recording::context *ctxt = block->get_context ();
3004 : 420 : JIT_LOG_FUNC (ctxt->get_logger ());
3005 : : /* LOC can be NULL. */
3006 : 420 : RETURN_IF_FAIL (text, ctxt, loc, "NULL text");
3007 : :
3008 : 420 : block->add_comment (loc, text);
3009 : 420 : }
3010 : :
3011 : : /* Public entrypoint. See description in libgccjit.h.
3012 : :
3013 : : After error-checking, the real work is done by the
3014 : : gcc::jit::recording::block::end_with_jump method in
3015 : : jit-recording.cc. */
3016 : :
3017 : : void
3018 : 1177 : gcc_jit_block_end_with_jump (gcc_jit_block *block,
3019 : : gcc_jit_location *loc,
3020 : : gcc_jit_block *target)
3021 : : {
3022 : 1182 : RETURN_IF_NOT_VALID_BLOCK (block, loc);
3023 : 1177 : gcc::jit::recording::context *ctxt = block->get_context ();
3024 : 1177 : JIT_LOG_FUNC (ctxt->get_logger ());
3025 : : /* LOC can be NULL. */
3026 : 1177 : RETURN_IF_FAIL (target, ctxt, loc, "NULL target");
3027 : 1177 : RETURN_IF_FAIL_PRINTF4 (
3028 : : block->get_function () == target->get_function (),
3029 : : ctxt, loc,
3030 : : "target block is not in same function:"
3031 : : " source block %s is in function %s"
3032 : : " whereas target block %s is in function %s",
3033 : : block->get_debug_string (),
3034 : : block->get_function ()->get_debug_string (),
3035 : : target->get_debug_string (),
3036 : : target->get_function ()->get_debug_string ());
3037 : :
3038 : 1172 : block->end_with_jump (loc, target);
3039 : 1177 : }
3040 : :
3041 : : /* Public entrypoint. See description in libgccjit.h.
3042 : :
3043 : : After error-checking, the real work is done by the
3044 : : gcc::jit::recording::block::end_with_return method in
3045 : : jit-recording.cc. */
3046 : :
3047 : : void
3048 : 4054 : gcc_jit_block_end_with_return (gcc_jit_block *block,
3049 : : gcc_jit_location *loc,
3050 : : gcc_jit_rvalue *rvalue)
3051 : : {
3052 : 4427 : RETURN_IF_NOT_VALID_BLOCK (block, loc);
3053 : 3572 : gcc::jit::recording::context *ctxt = block->get_context ();
3054 : 3572 : JIT_LOG_FUNC (ctxt->get_logger ());
3055 : : /* LOC can be NULL. */
3056 : 3572 : gcc::jit::recording::function *func = block->get_function ();
3057 : 3572 : RETURN_IF_FAIL (rvalue, ctxt, loc, "NULL rvalue");
3058 : 3516 : RETURN_IF_FAIL_PRINTF4 (
3059 : : compatible_types (
3060 : : func->get_return_type (),
3061 : : rvalue->get_type ()),
3062 : : ctxt, loc,
3063 : : "mismatching types:"
3064 : : " return of %s (type: %s) in function %s (return type: %s)",
3065 : : rvalue->get_debug_string (),
3066 : : rvalue->get_type ()->get_debug_string (),
3067 : : func->get_debug_string (),
3068 : : func->get_return_type ()->get_debug_string ());
3069 : :
3070 : 3199 : gcc::jit::recording::statement *stmt = block->end_with_return (loc, rvalue);
3071 : :
3072 : : /* "stmt" should be good enough to be usable in error-messages,
3073 : : but might still not be compilable; perform some more
3074 : : error-checking here. We do this here so that the error messages
3075 : : can contain a stringified version of "stmt", whilst appearing
3076 : : as close as possible to the point of failure. */
3077 : 3199 : rvalue->verify_valid_within_stmt (__func__, stmt);
3078 : 3572 : }
3079 : :
3080 : : /* Public entrypoint. See description in libgccjit.h.
3081 : :
3082 : : After error-checking, the real work is done by the
3083 : : gcc::jit::recording::block::end_with_return method in
3084 : : jit-recording.cc. */
3085 : :
3086 : : void
3087 : 586 : gcc_jit_block_end_with_void_return (gcc_jit_block *block,
3088 : : gcc_jit_location *loc)
3089 : : {
3090 : 586 : RETURN_IF_NOT_VALID_BLOCK (block, loc);
3091 : 581 : gcc::jit::recording::context *ctxt = block->get_context ();
3092 : 581 : JIT_LOG_FUNC (ctxt->get_logger ());
3093 : : /* LOC can be NULL. */
3094 : 581 : gcc::jit::recording::function *func = block->get_function ();
3095 : 581 : RETURN_IF_FAIL_PRINTF2 (
3096 : : func->get_return_type () == ctxt->get_type (GCC_JIT_TYPE_VOID),
3097 : : ctxt, loc,
3098 : : "mismatching types:"
3099 : : " void return in function %s (return type: %s)",
3100 : : func->get_debug_string (),
3101 : : func->get_return_type ()->get_debug_string ());
3102 : :
3103 : 581 : block->end_with_return (loc, NULL);
3104 : 581 : }
3105 : :
3106 : : /* Public entrypoint. See description in libgccjit.h.
3107 : :
3108 : : After error-checking, the real work is done by the
3109 : : gcc::jit::recording::context::new_case method in
3110 : : jit-recording.cc. */
3111 : :
3112 : : gcc_jit_case *
3113 : 110 : gcc_jit_context_new_case (gcc_jit_context *ctxt,
3114 : : gcc_jit_rvalue *min_value,
3115 : : gcc_jit_rvalue *max_value,
3116 : : gcc_jit_block *block)
3117 : : {
3118 : 110 : RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
3119 : 110 : JIT_LOG_FUNC (ctxt->get_logger ());
3120 : 110 : RETURN_NULL_IF_FAIL (min_value, ctxt, NULL, "NULL min_value");
3121 : 110 : RETURN_NULL_IF_FAIL (max_value, ctxt, NULL, "NULL max_value");
3122 : 110 : RETURN_NULL_IF_FAIL (block, ctxt, NULL, "NULL block");
3123 : :
3124 : 110 : RETURN_NULL_IF_FAIL_PRINTF1 (min_value->is_constant (), ctxt, NULL,
3125 : : "min_value is not a constant: %s",
3126 : : min_value->get_debug_string ());
3127 : 105 : RETURN_NULL_IF_FAIL_PRINTF1 (max_value->is_constant (), ctxt, NULL,
3128 : : "max_value is not a constant: %s",
3129 : : max_value->get_debug_string ());
3130 : 105 : RETURN_NULL_IF_FAIL_PRINTF2 (
3131 : : min_value->get_type ()->is_int (),
3132 : : ctxt, NULL,
3133 : : "min_value: %s (type: %s) is not of integer type",
3134 : : min_value->get_debug_string (),
3135 : : min_value->get_type ()->get_debug_string ());
3136 : 100 : RETURN_NULL_IF_FAIL_PRINTF2 (
3137 : : max_value->get_type ()->is_int (),
3138 : : ctxt, NULL,
3139 : : "max_value: %s (type: %s) is not of integer type",
3140 : : max_value->get_debug_string (),
3141 : : max_value->get_type ()->get_debug_string ());
3142 : :
3143 : 100 : wide_int wi_min, wi_max;
3144 : 100 : if (!min_value->get_wide_int (&wi_min))
3145 : 0 : gcc_unreachable ();
3146 : 100 : if (!max_value->get_wide_int (&wi_max))
3147 : 0 : gcc_unreachable ();
3148 : 100 : RETURN_NULL_IF_FAIL_PRINTF2 (
3149 : : wi::les_p (wi_min, wi_max),
3150 : : ctxt, NULL,
3151 : : "min_value: %s > max_value: %s",
3152 : : min_value->get_debug_string (),
3153 : : max_value->get_debug_string ());
3154 : 95 : return (gcc_jit_case *)ctxt->new_case (min_value,
3155 : : max_value,
3156 : 95 : block);
3157 : 110 : }
3158 : :
3159 : : /* Public entrypoint. See description in libgccjit.h.
3160 : :
3161 : : After error-checking, this calls the trivial
3162 : : gcc::jit::recording::memento::as_object method (a case is a
3163 : : memento), in jit-recording.h. */
3164 : :
3165 : : gcc_jit_object *
3166 : 20 : gcc_jit_case_as_object (gcc_jit_case *case_)
3167 : : {
3168 : 20 : RETURN_NULL_IF_FAIL (case_, NULL, NULL, "NULL case");
3169 : :
3170 : 20 : return static_cast <gcc_jit_object *> (case_->as_object ());
3171 : : }
3172 : :
3173 : : /* Helper function for gcc_jit_block_end_with_switch and
3174 : : valid_case_for_switch. */
3175 : :
3176 : : static bool
3177 : 145 : valid_dest_for_switch (gcc::jit::recording::context *ctxt,
3178 : : gcc_jit_location *loc,
3179 : : const char *api_funcname,
3180 : : gcc::jit::recording::block *switch_block,
3181 : : gcc::jit::recording::block *dest_block,
3182 : : const char *dest_block_desc)
3183 : : {
3184 : 145 : if (!dest_block)
3185 : : {
3186 : 0 : jit_error (ctxt, loc, "%s: NULL %s", api_funcname, dest_block_desc);
3187 : 0 : return false;
3188 : : }
3189 : 145 : gcc::jit::recording::function *switch_fn = switch_block->get_function ();
3190 : 145 : gcc::jit::recording::function *dest_fn = dest_block->get_function ();
3191 : 145 : if (switch_fn != dest_fn)
3192 : : {
3193 : 0 : jit_error (ctxt, loc,
3194 : : "%s: %s is not in same function:"
3195 : : " switch block %s is in function %s"
3196 : : " whereas %s %s is in function %s",
3197 : : api_funcname,
3198 : : dest_block_desc,
3199 : : switch_block->get_debug_string (),
3200 : : switch_fn->get_debug_string (),
3201 : : dest_block_desc,
3202 : : dest_block->get_debug_string (),
3203 : : dest_fn->get_debug_string ());
3204 : 0 : return false;
3205 : : }
3206 : : return true;
3207 : : }
3208 : :
3209 : : /* Helper function for gcc_jit_block_end_with_switch. */
3210 : :
3211 : : static bool
3212 : 115 : valid_case_for_switch (gcc::jit::recording::context *ctxt,
3213 : : gcc_jit_location *loc,
3214 : : const char *api_funcname,
3215 : : gcc_jit_block *switch_block,
3216 : : gcc_jit_rvalue *expr,
3217 : : gcc_jit_case *case_,
3218 : : const char *case_desc,
3219 : : int case_idx)
3220 : : {
3221 : 115 : if (!case_)
3222 : : {
3223 : 20 : jit_error (ctxt, loc,
3224 : : "%s:"
3225 : : " NULL case %i",
3226 : : api_funcname,
3227 : : case_idx);
3228 : 20 : return false;
3229 : : }
3230 : 95 : if (!valid_dest_for_switch (ctxt, loc,
3231 : : api_funcname,
3232 : : switch_block,
3233 : : case_->get_dest_block (),
3234 : : case_desc))
3235 : : return false;
3236 : 95 : gcc::jit::recording::type *expr_type = expr->get_type ();
3237 : 95 : if (expr_type != case_->get_min_value ()->get_type ())
3238 : : {
3239 : 5 : jit_error (ctxt, loc,
3240 : : "%s:"
3241 : : " mismatching types between case and expression:"
3242 : : " cases[%i]->min_value: %s (type: %s)"
3243 : : " expr: %s (type: %s)",
3244 : : api_funcname,
3245 : : case_idx,
3246 : 5 : case_->get_min_value ()->get_debug_string (),
3247 : 5 : case_->get_min_value ()->get_type ()->get_debug_string (),
3248 : : expr->get_debug_string (),
3249 : : expr_type->get_debug_string ());
3250 : 5 : return false;
3251 : : }
3252 : 90 : if (expr_type != case_->get_max_value ()->get_type ())
3253 : : {
3254 : 0 : jit_error (ctxt, loc,
3255 : : "%s:"
3256 : : " mismatching types between case and expression:"
3257 : : " cases[%i]->max_value: %s (type: %s)"
3258 : : " expr: %s (type: %s)",
3259 : : api_funcname,
3260 : : case_idx,
3261 : 0 : case_->get_max_value ()->get_debug_string (),
3262 : 0 : case_->get_max_value ()->get_type ()->get_debug_string (),
3263 : : expr->get_debug_string (),
3264 : : expr_type->get_debug_string ());
3265 : 0 : return false;
3266 : : }
3267 : : return true;
3268 : : }
3269 : :
3270 : : /* A class for holding the data we need to perform error-checking
3271 : : on a libgccjit API call. */
3272 : :
3273 : : class api_call_validator
3274 : : {
3275 : : public:
3276 : 50 : api_call_validator (gcc::jit::recording::context *ctxt,
3277 : : gcc_jit_location *loc,
3278 : : const char *funcname)
3279 : 50 : : m_ctxt (ctxt),
3280 : 50 : m_loc (loc),
3281 : 50 : m_funcname (funcname)
3282 : : {}
3283 : :
3284 : : protected:
3285 : : gcc::jit::recording::context *m_ctxt;
3286 : : gcc_jit_location *m_loc;
3287 : : const char *m_funcname;
3288 : : };
3289 : :
3290 : : /* A class for verifying that the ranges of cases within
3291 : : gcc_jit_block_end_with_switch don't overlap. */
3292 : :
3293 : 100 : class case_range_validator : public api_call_validator
3294 : : {
3295 : : public:
3296 : : case_range_validator (gcc::jit::recording::context *ctxt,
3297 : : gcc_jit_location *loc,
3298 : : const char *funcname);
3299 : :
3300 : : bool
3301 : : validate (gcc_jit_case *case_, int idx);
3302 : :
3303 : : private:
3304 : : static int
3305 : : case_compare (gcc::jit::recording::rvalue *k1,
3306 : : gcc::jit::recording::rvalue *k2);
3307 : :
3308 : : static wide_int
3309 : : get_wide_int (gcc::jit::recording::rvalue *k);
3310 : :
3311 : : private:
3312 : : typed_splay_tree <gcc::jit::recording::rvalue *, gcc_jit_case *> m_cases;
3313 : : };
3314 : :
3315 : : /* case_range_validator's ctor. */
3316 : :
3317 : 50 : case_range_validator::case_range_validator (gcc::jit::recording::context *ctxt,
3318 : : gcc_jit_location *loc,
3319 : 50 : const char *funcname)
3320 : : : api_call_validator (ctxt, loc, funcname),
3321 : 50 : m_cases (case_compare, NULL, NULL)
3322 : : {
3323 : 50 : }
3324 : :
3325 : : /* Ensure that the range of CASE_ does not overlap with any of the
3326 : : ranges of cases we've already seen.
3327 : : Return true if everything is OK.
3328 : : Return false and emit an error if there is an overlap.
3329 : : Compare with c-family/c-common.cc:c_add_case_label. */
3330 : :
3331 : : bool
3332 : 90 : case_range_validator::validate (gcc_jit_case *case_,
3333 : : int case_idx)
3334 : : {
3335 : : /* Look up the LOW_VALUE in the table of case labels we already
3336 : : have. */
3337 : 90 : gcc_jit_case *other = m_cases.lookup (case_->get_min_value ());
3338 : :
3339 : : /* If there was not an exact match, check for overlapping ranges. */
3340 : 0 : if (!other)
3341 : : {
3342 : 90 : gcc_jit_case *pred;
3343 : 90 : gcc_jit_case *succ;
3344 : :
3345 : : /* Even though there wasn't an exact match, there might be an
3346 : : overlap between this case range and another case range.
3347 : : Since we've (inductively) not allowed any overlapping case
3348 : : ranges, we simply need to find the greatest low case label
3349 : : that is smaller that CASE_MIN_VALUE, and the smallest low case
3350 : : label that is greater than CASE_MAX_VALUE. If there is an overlap
3351 : : it will occur in one of these two ranges. */
3352 : 90 : pred = m_cases.predecessor (case_->get_min_value ());
3353 : 90 : succ = m_cases.successor (case_->get_max_value ());
3354 : :
3355 : : /* Check to see if the PRED overlaps. It is smaller than
3356 : : the LOW_VALUE, so we only need to check its max value. */
3357 : 90 : if (pred)
3358 : : {
3359 : 45 : wide_int wi_case_min = get_wide_int (case_->get_min_value ());
3360 : 45 : wide_int wi_pred_max = get_wide_int (pred->get_max_value ());
3361 : 45 : if (wi::ges_p (wi_pred_max, wi_case_min))
3362 : 5 : other = pred;
3363 : 45 : }
3364 : :
3365 : 90 : if (!other && succ)
3366 : : {
3367 : : /* Check to see if the SUCC overlaps. The low end of that
3368 : : range is bigger than the low end of the current range. */
3369 : 20 : wide_int wi_case_max = get_wide_int (case_->get_max_value ());
3370 : 20 : wide_int wi_succ_min = get_wide_int (succ->get_min_value ());
3371 : 20 : if (wi::les_p (wi_succ_min, wi_case_max))
3372 : 0 : other = succ;
3373 : 20 : }
3374 : : }
3375 : :
3376 : : /* If there was an overlap, issue an error. */
3377 : 90 : if (other)
3378 : : {
3379 : 5 : jit_error (m_ctxt, m_loc,
3380 : : "%s: duplicate (or overlapping) cases values:"
3381 : : " case %i: %s overlaps %s",
3382 : : m_funcname,
3383 : : case_idx,
3384 : : case_->get_debug_string (),
3385 : : other->get_debug_string ());
3386 : 5 : return false;
3387 : : }
3388 : :
3389 : : /* Register this case label in the splay tree. */
3390 : 85 : m_cases.insert (case_->get_min_value (),
3391 : : case_);
3392 : 85 : return true;
3393 : : }
3394 : :
3395 : : /* Compare with c-family/c-common.cc:case_compare, which acts on tree
3396 : : nodes, rather than rvalue *.
3397 : :
3398 : : Comparator for case label values. K1 and K2 must be constant integer
3399 : : values (anything else should have been rejected by
3400 : : gcc_jit_context_new_case.
3401 : :
3402 : : Returns -1 if K1 is ordered before K2, -1 if K1 is ordered after
3403 : : K2, and 0 if K1 and K2 are equal. */
3404 : :
3405 : : int
3406 : 570 : case_range_validator::case_compare (gcc::jit::recording::rvalue * k1,
3407 : : gcc::jit::recording::rvalue * k2)
3408 : : {
3409 : 570 : wide_int wi1 = get_wide_int (k1);
3410 : 570 : wide_int wi2 = get_wide_int (k2);
3411 : 570 : return wi::cmps(wi1, wi2);
3412 : 570 : }
3413 : :
3414 : : /* Given a const int rvalue K, get the underlying value as a wide_int. */
3415 : :
3416 : : wide_int
3417 : 1270 : case_range_validator::get_wide_int (gcc::jit::recording::rvalue *k)
3418 : : {
3419 : 1270 : wide_int wi;
3420 : 1270 : bool got_wi = k->get_wide_int (&wi);
3421 : 1270 : gcc_assert (got_wi);
3422 : 1270 : return wi;
3423 : : }
3424 : :
3425 : : /* Public entrypoint. See description in libgccjit.h.
3426 : :
3427 : : After error-checking, the real work is done by the
3428 : : gcc::jit::recording::block::end_with_switch method in
3429 : : jit-recording.cc. */
3430 : :
3431 : : void
3432 : 50 : gcc_jit_block_end_with_switch (gcc_jit_block *block,
3433 : : gcc_jit_location *loc,
3434 : : gcc_jit_rvalue *expr,
3435 : : gcc_jit_block *default_block,
3436 : : int num_cases,
3437 : : gcc_jit_case **cases)
3438 : : {
3439 : 80 : RETURN_IF_NOT_VALID_BLOCK (block, loc);
3440 : 50 : gcc::jit::recording::context *ctxt = block->get_context ();
3441 : 50 : JIT_LOG_FUNC (ctxt->get_logger ());
3442 : : /* LOC can be NULL. */
3443 : 50 : RETURN_IF_FAIL (expr, ctxt, loc,
3444 : : "NULL expr");
3445 : 50 : gcc::jit::recording::type *expr_type = expr->get_type ();
3446 : 50 : RETURN_IF_FAIL_PRINTF2 (
3447 : : expr_type->is_int (),
3448 : : ctxt, loc,
3449 : : "expr: %s (type: %s) is not of integer type",
3450 : : expr->get_debug_string (),
3451 : : expr_type->get_debug_string ());
3452 : 50 : if (!valid_dest_for_switch (ctxt, loc,
3453 : : __func__,
3454 : : block,
3455 : : default_block,
3456 : : "default_block"))
3457 : : return;
3458 : 50 : RETURN_IF_FAIL (num_cases >= 0, ctxt, loc, "num_cases < 0");
3459 : 50 : case_range_validator crv (ctxt, loc, __func__);
3460 : 135 : for (int i = 0; i < num_cases; i++)
3461 : : {
3462 : 115 : char case_desc[32];
3463 : 115 : snprintf (case_desc, sizeof (case_desc),
3464 : : "cases[%i]", i);
3465 : 115 : if (!valid_case_for_switch (ctxt, loc,
3466 : : __func__,
3467 : : block,
3468 : : expr,
3469 : 115 : cases[i],
3470 : : case_desc,
3471 : : i))
3472 : 30 : return;
3473 : 90 : if (!crv.validate (cases[i], i))
3474 : : return;
3475 : : }
3476 : :
3477 : 20 : block->end_with_switch (loc, expr, default_block,
3478 : : num_cases,
3479 : : (gcc::jit::recording::case_ **)cases);
3480 : 50 : }
3481 : :
3482 : : /**********************************************************************
3483 : : Option-management
3484 : : **********************************************************************/
3485 : :
3486 : : /* Public entrypoint. See description in libgccjit.h.
3487 : :
3488 : : After error-checking, the real work is done by the
3489 : : gcc::jit::recording::context::set_str_option method in
3490 : : jit-recording.cc. */
3491 : :
3492 : : void
3493 : 1637 : gcc_jit_context_set_str_option (gcc_jit_context *ctxt,
3494 : : enum gcc_jit_str_option opt,
3495 : : const char *value)
3496 : : {
3497 : 1637 : RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
3498 : 1637 : JIT_LOG_FUNC (ctxt->get_logger ());
3499 : : /* opt is checked by the inner function.
3500 : : value can be NULL. */
3501 : :
3502 : 1637 : ctxt->set_str_option (opt, value);
3503 : 1637 : }
3504 : :
3505 : : /* Public entrypoint. See description in libgccjit.h.
3506 : :
3507 : : After error-checking, the real work is done by the
3508 : : gcc::jit::recording::context::set_int_option method in
3509 : : jit-recording.cc. */
3510 : :
3511 : : void
3512 : 1692 : gcc_jit_context_set_int_option (gcc_jit_context *ctxt,
3513 : : enum gcc_jit_int_option opt,
3514 : : int value)
3515 : : {
3516 : 1692 : RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
3517 : 1692 : JIT_LOG_FUNC (ctxt->get_logger ());
3518 : : /* opt is checked by the inner function. */
3519 : :
3520 : 1692 : ctxt->set_int_option (opt, value);
3521 : 1692 : }
3522 : :
3523 : : /* Public entrypoint. See description in libgccjit.h.
3524 : :
3525 : : After error-checking, the real work is done by the
3526 : : gcc::jit::recording::context::set_bool_option method in
3527 : : jit-recording.cc. */
3528 : :
3529 : : void
3530 : 6995 : gcc_jit_context_set_bool_option (gcc_jit_context *ctxt,
3531 : : enum gcc_jit_bool_option opt,
3532 : : int value)
3533 : : {
3534 : 6995 : RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
3535 : 6995 : JIT_LOG_FUNC (ctxt->get_logger ());
3536 : : /* opt is checked by the inner function. */
3537 : :
3538 : 6995 : ctxt->set_bool_option (opt, value);
3539 : 6995 : }
3540 : :
3541 : : /* Public entrypoint. See description in libgccjit.h.
3542 : :
3543 : : After error-checking, the real work is done by the
3544 : : gcc::jit::recording::context::set_inner_bool_option method in
3545 : : jit-recording.cc. */
3546 : :
3547 : : void
3548 : 5 : gcc_jit_context_set_bool_allow_unreachable_blocks (gcc_jit_context *ctxt,
3549 : : int bool_value)
3550 : : {
3551 : 5 : RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
3552 : 5 : JIT_LOG_FUNC (ctxt->get_logger ());
3553 : 5 : ctxt->set_inner_bool_option (
3554 : : gcc::jit::INNER_BOOL_OPTION_ALLOW_UNREACHABLE_BLOCKS,
3555 : : bool_value);
3556 : 5 : }
3557 : :
3558 : : /* Public entrypoint. See description in libgccjit.h.
3559 : :
3560 : : After error-checking, the real work is done by the
3561 : : gcc::jit::recording::context::set_inner_bool_option method in
3562 : : jit-recording.cc. */
3563 : :
3564 : : void
3565 : 0 : gcc_jit_context_set_bool_print_errors_to_stderr (gcc_jit_context *ctxt,
3566 : : int enabled)
3567 : : {
3568 : 0 : RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
3569 : 0 : JIT_LOG_FUNC (ctxt->get_logger ());
3570 : 0 : ctxt->set_inner_bool_option (
3571 : : gcc::jit::INNER_BOOL_OPTION_PRINT_ERRORS_TO_STDERR,
3572 : : enabled);
3573 : 0 : }
3574 : :
3575 : : /* Public entrypoint. See description in libgccjit.h.
3576 : :
3577 : : After error-checking, the real work is done by the
3578 : : gcc::jit::recording::context::set_inner_bool_option method in
3579 : : jit-recording.cc. */
3580 : :
3581 : : extern void
3582 : 5 : gcc_jit_context_set_bool_use_external_driver (gcc_jit_context *ctxt,
3583 : : int bool_value)
3584 : : {
3585 : 5 : RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
3586 : 5 : JIT_LOG_FUNC (ctxt->get_logger ());
3587 : 5 : ctxt->set_inner_bool_option (
3588 : : gcc::jit::INNER_BOOL_OPTION_USE_EXTERNAL_DRIVER,
3589 : : bool_value);
3590 : 5 : }
3591 : :
3592 : : /* Public entrypoint. See description in libgccjit.h.
3593 : :
3594 : : After error-checking, the real work is done by the
3595 : : gcc::jit::recording::context::add_command_line_option method in
3596 : : jit-recording.cc. */
3597 : :
3598 : : void
3599 : 1267 : gcc_jit_context_add_command_line_option (gcc_jit_context *ctxt,
3600 : : const char *optname)
3601 : : {
3602 : 1267 : RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
3603 : 1267 : JIT_LOG_FUNC (ctxt->get_logger ());
3604 : 1267 : RETURN_IF_FAIL (optname, ctxt, NULL, "NULL optname");
3605 : 1267 : if (ctxt->get_logger ())
3606 : 1022 : ctxt->get_logger ()->log ("optname: %s", optname);
3607 : :
3608 : 1267 : ctxt->add_command_line_option (optname);
3609 : 1267 : }
3610 : :
3611 : : /* Public entrypoint. See description in libgccjit.h.
3612 : :
3613 : : The real work is done by the
3614 : : gcc::jit::recording::context::add_driver_option method in
3615 : : jit-recording.cc. */
3616 : :
3617 : : void
3618 : 15 : gcc_jit_context_add_driver_option (gcc_jit_context *ctxt,
3619 : : const char *optname)
3620 : : {
3621 : 15 : RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
3622 : 15 : JIT_LOG_FUNC (ctxt->get_logger ());
3623 : 15 : RETURN_IF_FAIL (optname, ctxt, NULL, "NULL optname");
3624 : 15 : if (ctxt->get_logger ())
3625 : 15 : ctxt->get_logger ()->log ("optname: %s", optname);
3626 : :
3627 : 15 : ctxt->add_driver_option (optname);
3628 : 15 : }
3629 : :
3630 : : /* Public entrypoint. See description in libgccjit.h.
3631 : :
3632 : : After error-checking, the real work is done by the
3633 : : gcc::jit::recording::context::enable_dump method in
3634 : : jit-recording.cc. */
3635 : :
3636 : : void
3637 : 50 : gcc_jit_context_enable_dump (gcc_jit_context *ctxt,
3638 : : const char *dumpname,
3639 : : char **out_ptr)
3640 : : {
3641 : 50 : RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
3642 : 50 : JIT_LOG_FUNC (ctxt->get_logger ());
3643 : 50 : RETURN_IF_FAIL (dumpname, ctxt, NULL, "NULL dumpname");
3644 : 50 : RETURN_IF_FAIL (out_ptr, ctxt, NULL, "NULL out_ptr");
3645 : :
3646 : 50 : ctxt->enable_dump (dumpname, out_ptr);
3647 : 50 : }
3648 : :
3649 : : /* Public entrypoint. See description in libgccjit.h.
3650 : :
3651 : : After error-checking, the real work is done by the
3652 : : gcc::jit::recording::context::compile method in
3653 : : jit-recording.cc. */
3654 : :
3655 : : gcc_jit_result *
3656 : 1612 : gcc_jit_context_compile (gcc_jit_context *ctxt)
3657 : : {
3658 : 1612 : RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
3659 : :
3660 : 1612 : JIT_LOG_FUNC (ctxt->get_logger ());
3661 : :
3662 : 1612 : ctxt->log ("in-memory compile of ctxt: %p", (void *)ctxt);
3663 : :
3664 : 1612 : gcc_jit_result *result = (gcc_jit_result *)ctxt->compile ();
3665 : :
3666 : 1612 : ctxt->log ("%s: returning (gcc_jit_result *)%p",
3667 : : __func__, (void *)result);
3668 : :
3669 : 1612 : return result;
3670 : 1612 : }
3671 : :
3672 : : /* Public entrypoint. See description in libgccjit.h.
3673 : :
3674 : : After error-checking, the real work is done by the
3675 : : gcc::jit::recording::context::compile_to_file method in
3676 : : jit-recording.cc. */
3677 : :
3678 : : void
3679 : 101 : gcc_jit_context_compile_to_file (gcc_jit_context *ctxt,
3680 : : enum gcc_jit_output_kind output_kind,
3681 : : const char *output_path)
3682 : : {
3683 : 101 : RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
3684 : 101 : JIT_LOG_FUNC (ctxt->get_logger ());
3685 : 101 : RETURN_IF_FAIL_PRINTF1 (
3686 : : ((output_kind >= GCC_JIT_OUTPUT_KIND_ASSEMBLER)
3687 : : && (output_kind <= GCC_JIT_OUTPUT_KIND_EXECUTABLE)),
3688 : : ctxt, NULL,
3689 : : "unrecognized output_kind: %i",
3690 : : output_kind);
3691 : 101 : RETURN_IF_FAIL (output_path, ctxt, NULL, "NULL output_path");
3692 : :
3693 : 101 : ctxt->log ("compile_to_file of ctxt: %p", (void *)ctxt);
3694 : 101 : ctxt->log ("output_kind: %i", output_kind);
3695 : 101 : ctxt->log ("output_path: %s", output_path);
3696 : :
3697 : 101 : ctxt->compile_to_file (output_kind, output_path);
3698 : 101 : }
3699 : :
3700 : :
3701 : : /* Public entrypoint. See description in libgccjit.h.
3702 : :
3703 : : After error-checking, the real work is done by the
3704 : : gcc::jit::recording::context::dump_to_file method in
3705 : : jit-recording.cc. */
3706 : :
3707 : : void
3708 : 14 : gcc_jit_context_dump_to_file (gcc_jit_context *ctxt,
3709 : : const char *path,
3710 : : int update_locations)
3711 : : {
3712 : 14 : RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
3713 : 14 : JIT_LOG_FUNC (ctxt->get_logger ());
3714 : 14 : RETURN_IF_FAIL (path, ctxt, NULL, "NULL path");
3715 : 14 : ctxt->dump_to_file (path, update_locations);
3716 : 14 : }
3717 : :
3718 : : /* Public entrypoint. See description in libgccjit.h. */
3719 : :
3720 : : void
3721 : 1047 : gcc_jit_context_set_logfile (gcc_jit_context *ctxt,
3722 : : FILE *logfile,
3723 : : int flags,
3724 : : int verbosity)
3725 : : {
3726 : 1047 : RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
3727 : 1047 : JIT_LOG_FUNC (ctxt->get_logger ());
3728 : 1047 : RETURN_IF_FAIL ((flags == 0), ctxt, NULL, "flags must be 0 for now");
3729 : 1047 : RETURN_IF_FAIL ((verbosity == 0), ctxt, NULL, "verbosity must be 0 for now");
3730 : :
3731 : 1047 : gcc::jit::logger *logger;
3732 : 1047 : if (logfile)
3733 : 1047 : logger = new gcc::jit::logger (logfile, flags, verbosity);
3734 : : else
3735 : : logger = NULL;
3736 : 1047 : ctxt->set_logger (logger);
3737 : 1047 : }
3738 : :
3739 : : /* Public entrypoint. See description in libgccjit.h.
3740 : :
3741 : : After error-checking, the real work is done by the
3742 : : gcc::jit::recording::context::dump_reproducer_to_file method in
3743 : : jit-recording.cc. */
3744 : :
3745 : : void
3746 : 1053 : gcc_jit_context_dump_reproducer_to_file (gcc_jit_context *ctxt,
3747 : : const char *path)
3748 : : {
3749 : 1053 : RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
3750 : 1053 : JIT_LOG_FUNC (ctxt->get_logger ());
3751 : 1053 : RETURN_IF_FAIL (path, ctxt, NULL, "NULL path");
3752 : 1053 : ctxt->dump_reproducer_to_file (path);
3753 : 1053 : }
3754 : :
3755 : : /* Public entrypoint. See description in libgccjit.h.
3756 : :
3757 : : After error-checking, the real work is done by the
3758 : : gcc::jit::recording::context::get_first_error method in
3759 : : jit-recording.cc. */
3760 : :
3761 : : const char *
3762 : 500 : gcc_jit_context_get_first_error (gcc_jit_context *ctxt)
3763 : : {
3764 : 500 : RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
3765 : 500 : JIT_LOG_FUNC (ctxt->get_logger ());
3766 : :
3767 : 500 : return ctxt->get_first_error ();
3768 : 500 : }
3769 : :
3770 : : /* Public entrypoint. See description in libgccjit.h.
3771 : :
3772 : : After error-checking, the real work is done by the
3773 : : gcc::jit::recording::context::get_last_error method in
3774 : : jit-recording.cc. */
3775 : :
3776 : : const char *
3777 : 80 : gcc_jit_context_get_last_error (gcc_jit_context *ctxt)
3778 : : {
3779 : 80 : RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
3780 : :
3781 : 80 : return ctxt->get_last_error ();
3782 : : }
3783 : :
3784 : : /* Public entrypoint. See description in libgccjit.h.
3785 : :
3786 : : After error-checking, the real work is done by the
3787 : : gcc::jit::result::get_code method in jit-result.cc. */
3788 : :
3789 : : void *
3790 : 2747 : gcc_jit_result_get_code (gcc_jit_result *result,
3791 : : const char *fnname)
3792 : : {
3793 : 2747 : RETURN_NULL_IF_FAIL (result, NULL, NULL, "NULL result");
3794 : 2747 : JIT_LOG_FUNC (result->get_logger ());
3795 : 2747 : RETURN_NULL_IF_FAIL (fnname, NULL, NULL, "NULL fnname");
3796 : :
3797 : 2747 : result->log ("locating fnname: %s", fnname);
3798 : 2747 : void *code = result->get_code (fnname);
3799 : 2747 : result->log ("%s: returning (void *)%p", __func__, code);
3800 : :
3801 : 2747 : return code;
3802 : 2747 : }
3803 : :
3804 : : /* Public entrypoint. See description in libgccjit.h.
3805 : :
3806 : : After error-checking, the real work is done by the
3807 : : gcc::jit::result::get_global method in jit-result.cc. */
3808 : :
3809 : : void *
3810 : 680 : gcc_jit_result_get_global (gcc_jit_result *result,
3811 : : const char *name)
3812 : : {
3813 : 680 : RETURN_NULL_IF_FAIL (result, NULL, NULL, "NULL result");
3814 : 680 : JIT_LOG_FUNC (result->get_logger ());
3815 : 680 : RETURN_NULL_IF_FAIL (name, NULL, NULL, "NULL name");
3816 : :
3817 : 680 : void *global = result->get_global (name);
3818 : 680 : result->log ("%s: returning (void *)%p", __func__, global);
3819 : :
3820 : 680 : return global;
3821 : 680 : }
3822 : :
3823 : : /* Public entrypoint. See description in libgccjit.h.
3824 : :
3825 : : After error-checking, this is essentially a wrapper around the
3826 : : destructor for gcc::jit::result in jit-result.cc. */
3827 : :
3828 : : void
3829 : 1612 : gcc_jit_result_release (gcc_jit_result *result)
3830 : : {
3831 : 1612 : RETURN_IF_FAIL (result, NULL, NULL, "NULL result");
3832 : 1017 : JIT_LOG_FUNC (result->get_logger ());
3833 : 1017 : result->log ("deleting result: %p", (void *)result);
3834 : 1017 : delete result;
3835 : 1017 : }
3836 : :
3837 : : /**********************************************************************
3838 : : Timing support.
3839 : : **********************************************************************/
3840 : :
3841 : : /* Create a gcc_jit_timer instance, and start timing. */
3842 : :
3843 : : gcc_jit_timer *
3844 : 14 : gcc_jit_timer_new (void)
3845 : : {
3846 : 14 : gcc_jit_timer *timer = new gcc_jit_timer ();
3847 : 14 : timer->start (TV_TOTAL);
3848 : 14 : timer->push (TV_JIT_CLIENT_CODE);
3849 : 14 : return timer;
3850 : : }
3851 : :
3852 : : /* Release a gcc_jit_timer instance. */
3853 : :
3854 : : void
3855 : 14 : gcc_jit_timer_release (gcc_jit_timer *timer)
3856 : : {
3857 : 14 : RETURN_IF_FAIL (timer, NULL, NULL, "NULL timer");
3858 : :
3859 : 14 : delete timer;
3860 : : }
3861 : :
3862 : : /* Associate a gcc_jit_timer instance with a context. */
3863 : :
3864 : : void
3865 : 400 : gcc_jit_context_set_timer (gcc_jit_context *ctxt,
3866 : : gcc_jit_timer *timer)
3867 : : {
3868 : 400 : RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL ctxt");
3869 : 400 : RETURN_IF_FAIL (timer, ctxt, NULL, "NULL timer");
3870 : :
3871 : 400 : ctxt->set_timer (timer);
3872 : : }
3873 : :
3874 : : /* Get the timer associated with a context (if any). */
3875 : :
3876 : : gcc_jit_timer *
3877 : 0 : gcc_jit_context_get_timer (gcc_jit_context *ctxt)
3878 : : {
3879 : 0 : RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL ctxt");
3880 : :
3881 : 0 : return (gcc_jit_timer *)ctxt->get_timer ();
3882 : : }
3883 : :
3884 : : /* Push the given item onto the timing stack. */
3885 : :
3886 : : void
3887 : 1605 : gcc_jit_timer_push (gcc_jit_timer *timer,
3888 : : const char *item_name)
3889 : : {
3890 : 1605 : RETURN_IF_FAIL (timer, NULL, NULL, "NULL timer");
3891 : 1605 : RETURN_IF_FAIL (item_name, NULL, NULL, "NULL item_name");
3892 : 1605 : timer->push_client_item (item_name);
3893 : : }
3894 : :
3895 : : /* Pop the top item from the timing stack. */
3896 : :
3897 : : void
3898 : 1610 : gcc_jit_timer_pop (gcc_jit_timer *timer,
3899 : : const char *item_name)
3900 : : {
3901 : 1610 : RETURN_IF_FAIL (timer, NULL, NULL, "NULL timer");
3902 : :
3903 : 1610 : if (item_name)
3904 : : {
3905 : 1610 : const char *top_item_name = timer->get_topmost_item_name ();
3906 : :
3907 : 1610 : RETURN_IF_FAIL_PRINTF1
3908 : : (top_item_name, NULL, NULL,
3909 : : "pop of empty timing stack (attempting to pop: \"%s\")",
3910 : : item_name);
3911 : :
3912 : 1610 : RETURN_IF_FAIL_PRINTF2
3913 : : (strcmp (item_name, top_item_name) == 0, NULL, NULL,
3914 : : "mismatching item_name:"
3915 : : " top of timing stack: \"%s\","
3916 : : " attempting to pop: \"%s\"",
3917 : : top_item_name,
3918 : : item_name);
3919 : : }
3920 : :
3921 : 1600 : timer->pop_client_item ();
3922 : : }
3923 : :
3924 : : /* Print timing information to the given stream about activity since
3925 : : the timer was started. */
3926 : :
3927 : : void
3928 : 4 : gcc_jit_timer_print (gcc_jit_timer *timer,
3929 : : FILE *f_out)
3930 : : {
3931 : 4 : RETURN_IF_FAIL (timer, NULL, NULL, "NULL timer");
3932 : 4 : RETURN_IF_FAIL (f_out, NULL, NULL, "NULL f_out");
3933 : :
3934 : 4 : timer->pop (TV_JIT_CLIENT_CODE);
3935 : 4 : timer->stop (TV_TOTAL);
3936 : 4 : timer->print (f_out);
3937 : 4 : timer->start (TV_TOTAL);
3938 : 4 : timer->push (TV_JIT_CLIENT_CODE);
3939 : : }
3940 : :
3941 : : /* Public entrypoint. See description in libgccjit.h.
3942 : :
3943 : : After error-checking, the real work is effectively done by the
3944 : : gcc::jit::base_call::set_require_tail_call setter in jit-recording.h. */
3945 : :
3946 : : void
3947 : 20 : gcc_jit_rvalue_set_bool_require_tail_call (gcc_jit_rvalue *rvalue,
3948 : : int require_tail_call)
3949 : : {
3950 : 20 : RETURN_IF_FAIL (rvalue, NULL, NULL, "NULL call");
3951 : 20 : JIT_LOG_FUNC (rvalue->get_context ()->get_logger ());
3952 : :
3953 : : /* Verify that it's a call. */
3954 : 20 : gcc::jit::recording::base_call *call = rvalue->dyn_cast_base_call ();
3955 : 20 : RETURN_IF_FAIL_PRINTF1 (call, NULL, NULL, "not a call: %s",
3956 : : rvalue->get_debug_string ());
3957 : :
3958 : 20 : call->set_require_tail_call (require_tail_call);
3959 : 20 : }
3960 : :
3961 : : /* Public entrypoint. See description in libgccjit.h.
3962 : :
3963 : : After error-checking, the real work is done by the
3964 : : gcc::jit::recording::type::get_aligned method, in
3965 : : jit-recording.cc. */
3966 : :
3967 : : gcc_jit_type *
3968 : 371 : gcc_jit_type_get_aligned (gcc_jit_type *type,
3969 : : size_t alignment_in_bytes)
3970 : : {
3971 : 371 : RETURN_NULL_IF_FAIL (type, NULL, NULL, "NULL type");
3972 : :
3973 : 369 : gcc::jit::recording::context *ctxt = type->m_ctxt;
3974 : :
3975 : 369 : JIT_LOG_FUNC (ctxt->get_logger ());
3976 : :
3977 : 369 : RETURN_NULL_IF_FAIL_PRINTF1
3978 : : (pow2_or_zerop (alignment_in_bytes), ctxt, NULL,
3979 : : "alignment not a power of two: %zi",
3980 : : alignment_in_bytes);
3981 : 364 : RETURN_NULL_IF_FAIL (!type->is_void (), ctxt, NULL, "void type");
3982 : :
3983 : 354 : return (gcc_jit_type *)type->get_aligned (alignment_in_bytes);
3984 : 369 : }
3985 : :
3986 : : void
3987 : 40 : gcc_jit_function_add_attribute (gcc_jit_function *func,
3988 : : gcc_jit_fn_attribute attribute)
3989 : : {
3990 : 40 : RETURN_IF_FAIL (func, NULL, NULL, "NULL func");
3991 : 40 : RETURN_IF_FAIL ((attribute >= 0 && attribute < GCC_JIT_FN_ATTRIBUTE_MAX),
3992 : : NULL,
3993 : : NULL,
3994 : : "attribute should be a `gcc_jit_fn_attribute` enum value");
3995 : :
3996 : 40 : func->add_attribute (attribute);
3997 : : }
3998 : :
3999 : : void
4000 : 5 : gcc_jit_function_add_string_attribute (gcc_jit_function *func,
4001 : : gcc_jit_fn_attribute attribute,
4002 : : const char* value)
4003 : : {
4004 : 5 : RETURN_IF_FAIL (func, NULL, NULL, "NULL func");
4005 : 5 : RETURN_IF_FAIL (value, NULL, NULL, "NULL value");
4006 : 5 : RETURN_IF_FAIL ((attribute >= 0 && attribute < GCC_JIT_FN_ATTRIBUTE_MAX),
4007 : : NULL,
4008 : : NULL,
4009 : : "attribute should be a `gcc_jit_fn_attribute` enum value");
4010 : :
4011 : 5 : func->add_string_attribute (attribute, value);
4012 : : }
4013 : :
4014 : : /* This function adds an attribute with multiple integer values. For example
4015 : : `nonnull(1, 2)`. The numbers in `values` are supposed to map how they
4016 : : should be written in C code. So for `nonnull(1, 2)`, you should pass `1`
4017 : : and `2` in `values` (and set `length` to `2`). */
4018 : : void
4019 : 5 : gcc_jit_function_add_integer_array_attribute (gcc_jit_function *func,
4020 : : gcc_jit_fn_attribute attribute,
4021 : : const int* values,
4022 : : size_t length)
4023 : : {
4024 : 5 : RETURN_IF_FAIL (func, NULL, NULL, "NULL func");
4025 : 5 : RETURN_IF_FAIL (values, NULL, NULL, "NULL values");
4026 : 5 : RETURN_IF_FAIL ((attribute >= 0 && attribute < GCC_JIT_FN_ATTRIBUTE_MAX),
4027 : : NULL,
4028 : : NULL,
4029 : : "attribute should be a `gcc_jit_fn_attribute` enum value");
4030 : :
4031 : 5 : func->add_integer_array_attribute (attribute, values, length);
4032 : : }
4033 : :
4034 : : void
4035 : 5 : gcc_jit_lvalue_add_string_attribute (gcc_jit_lvalue *variable,
4036 : : gcc_jit_variable_attribute attribute,
4037 : : const char* value)
4038 : : {
4039 : 5 : RETURN_IF_FAIL (variable, NULL, NULL, "NULL variable");
4040 : 5 : RETURN_IF_FAIL (value, NULL, NULL, "NULL value");
4041 : 5 : RETURN_IF_FAIL (variable->is_global () || variable->is_local (),
4042 : : NULL,
4043 : : NULL,
4044 : : "variable should be a variable");
4045 : 5 : RETURN_IF_FAIL ((attribute >= 0 && attribute < GCC_JIT_VARIABLE_ATTRIBUTE_MAX),
4046 : : NULL,
4047 : : NULL,
4048 : : "attribute should be a `gcc_jit_variable_attribute` enum value");
4049 : :
4050 : 5 : variable->add_string_attribute (attribute, value);
4051 : : }
4052 : :
4053 : : /* Public entrypoint. See description in libgccjit.h.
4054 : :
4055 : : After error-checking, the real work is done by the
4056 : : gcc::jit::recording::type::get_vector method, in
4057 : : jit-recording.cc. */
4058 : :
4059 : : gcc_jit_type *
4060 : 450 : gcc_jit_type_get_vector (gcc_jit_type *type, size_t num_units)
4061 : : {
4062 : 450 : RETURN_NULL_IF_FAIL (type, NULL, NULL, "NULL type");
4063 : :
4064 : 446 : gcc::jit::recording::context *ctxt = type->m_ctxt;
4065 : :
4066 : 446 : JIT_LOG_FUNC (ctxt->get_logger ());
4067 : :
4068 : 446 : RETURN_NULL_IF_FAIL_PRINTF1
4069 : : (type->is_int () || type->is_float (), ctxt, NULL,
4070 : : "type is not integral or floating point: %s",
4071 : : type->get_debug_string ());
4072 : :
4073 : 391 : RETURN_NULL_IF_FAIL_PRINTF1
4074 : : (pow2_or_zerop (num_units), ctxt, NULL,
4075 : : "num_units not a power of two: %zi",
4076 : : num_units);
4077 : :
4078 : 386 : return (gcc_jit_type *)type->get_vector (num_units);
4079 : 446 : }
4080 : :
4081 : : /* Public entrypoint. See description in libgccjit.h.
4082 : :
4083 : : After error-checking, the real work is done by the
4084 : : gcc::jit::recording::function::get_address method, in
4085 : : jit-recording.cc. */
4086 : :
4087 : : gcc_jit_rvalue *
4088 : 15 : gcc_jit_function_get_address (gcc_jit_function *fn,
4089 : : gcc_jit_location *loc)
4090 : : {
4091 : 15 : RETURN_NULL_IF_FAIL (fn, NULL, NULL, "NULL function");
4092 : :
4093 : 15 : gcc::jit::recording::context *ctxt = fn->m_ctxt;
4094 : :
4095 : 15 : JIT_LOG_FUNC (ctxt->get_logger ());
4096 : : /* LOC can be NULL. */
4097 : :
4098 : 15 : return (gcc_jit_rvalue *)fn->get_address (loc);
4099 : 15 : }
4100 : :
4101 : : /* Public entrypoint. See description in libgccjit.h.
4102 : :
4103 : : After error-checking, the real work is done by the
4104 : : gcc::jit::recording::context::new_rvalue_from_vector method, in
4105 : : jit-recording.cc. */
4106 : :
4107 : : extern gcc_jit_rvalue *
4108 : 75 : gcc_jit_context_new_rvalue_from_vector (gcc_jit_context *ctxt,
4109 : : gcc_jit_location *loc,
4110 : : gcc_jit_type *vec_type,
4111 : : size_t num_elements,
4112 : : gcc_jit_rvalue **elements)
4113 : : {
4114 : 75 : RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL ctxt");
4115 : 75 : JIT_LOG_FUNC (ctxt->get_logger ());
4116 : :
4117 : : /* LOC can be NULL. */
4118 : 75 : RETURN_NULL_IF_FAIL (vec_type, ctxt, loc, "NULL vec_type");
4119 : :
4120 : : /* "vec_type" must be a vector type. */
4121 : 75 : gcc::jit::recording::vector_type *as_vec_type
4122 : 75 : = vec_type->dyn_cast_vector_type ();
4123 : 75 : RETURN_NULL_IF_FAIL_PRINTF1 (as_vec_type, ctxt, loc,
4124 : : "%s is not a vector type",
4125 : : vec_type->get_debug_string ());
4126 : :
4127 : : /* "num_elements" must match. */
4128 : 75 : RETURN_NULL_IF_FAIL_PRINTF1 (
4129 : : num_elements == as_vec_type->get_num_units (), ctxt, loc,
4130 : : "num_elements != %zi", as_vec_type->get_num_units ());
4131 : :
4132 : : /* "elements must be non-NULL. */
4133 : 75 : RETURN_NULL_IF_FAIL (elements, ctxt, loc, "NULL elements");
4134 : :
4135 : : /* Each of "elements" must be non-NULL and of the correct type. */
4136 : 75 : gcc::jit::recording::type *element_type
4137 : 75 : = as_vec_type->get_element_type ();
4138 : 375 : for (size_t i = 0; i < num_elements; i++)
4139 : : {
4140 : 300 : RETURN_NULL_IF_FAIL_PRINTF1 (
4141 : : elements[i], ctxt, loc, "NULL elements[%zi]", i);
4142 : 300 : RETURN_NULL_IF_FAIL_PRINTF4 (
4143 : : compatible_types (element_type,
4144 : : elements[i]->get_type ()),
4145 : : ctxt, loc,
4146 : : "mismatching type for element[%zi] (expected type: %s): %s (type: %s)",
4147 : : i,
4148 : : element_type->get_debug_string (),
4149 : : elements[i]->get_debug_string (),
4150 : : elements[i]->get_type ()->get_debug_string ());
4151 : : }
4152 : :
4153 : 75 : return (gcc_jit_rvalue *)ctxt->new_rvalue_from_vector
4154 : 75 : (loc,
4155 : : as_vec_type,
4156 : 75 : (gcc::jit::recording::rvalue **)elements);
4157 : 75 : }
4158 : :
4159 : : /* A mutex around the cached state in parse_basever.
4160 : : Ideally this would be within parse_basever, but the mutex is only needed
4161 : : by libgccjit. */
4162 : :
4163 : : static std::mutex version_mutex;
4164 : :
4165 : : struct jit_version_info
4166 : : {
4167 : : /* Default constructor. Populate via parse_basever,
4168 : : guarded by version_mutex. */
4169 : 45 : jit_version_info ()
4170 : 45 : {
4171 : 45 : std::lock_guard<std::mutex> g (version_mutex);
4172 : 45 : parse_basever (&major, &minor, &patchlevel);
4173 : 45 : }
4174 : :
4175 : : int major;
4176 : : int minor;
4177 : : int patchlevel;
4178 : : };
4179 : :
4180 : :
4181 : : extern int
4182 : 15 : gcc_jit_version_major (void)
4183 : : {
4184 : 15 : jit_version_info vi;
4185 : 15 : return vi.major;
4186 : : }
4187 : :
4188 : : extern int
4189 : 15 : gcc_jit_version_minor (void)
4190 : : {
4191 : 15 : jit_version_info vi;
4192 : 15 : return vi.minor;
4193 : : }
4194 : :
4195 : : extern int
4196 : 15 : gcc_jit_version_patchlevel (void)
4197 : : {
4198 : 15 : jit_version_info vi;
4199 : 15 : return vi.patchlevel;
4200 : : }
4201 : :
4202 : : /**********************************************************************
4203 : : Asm support.
4204 : : **********************************************************************/
4205 : :
4206 : : /* Public entrypoint. See description in libgccjit.h.
4207 : :
4208 : : After error-checking, the real work is done by the
4209 : : gcc::jit::recording::block::add_extended_asm, in
4210 : : jit-recording.cc. */
4211 : :
4212 : : gcc_jit_extended_asm *
4213 : 50 : gcc_jit_block_add_extended_asm (gcc_jit_block *block,
4214 : : gcc_jit_location *loc,
4215 : : const char *asm_template)
4216 : : {
4217 : 50 : RETURN_NULL_IF_NOT_VALID_BLOCK (block, loc);
4218 : 50 : gcc::jit::recording::context *ctxt = block->get_context ();
4219 : 50 : JIT_LOG_FUNC (ctxt->get_logger ());
4220 : : /* LOC can be NULL. */
4221 : 50 : RETURN_NULL_IF_FAIL (asm_template, ctxt, loc, "NULL asm_template");
4222 : :
4223 : 50 : return (gcc_jit_extended_asm *)block->add_extended_asm (loc, asm_template);
4224 : 50 : }
4225 : :
4226 : : /* Public entrypoint. See description in libgccjit.h.
4227 : :
4228 : : After error-checking, the real work is done by the
4229 : : gcc::jit::recording::block::end_with_extended_asm_goto, in
4230 : : jit-recording.cc. */
4231 : :
4232 : : gcc_jit_extended_asm *
4233 : 20 : gcc_jit_block_end_with_extended_asm_goto (gcc_jit_block *block,
4234 : : gcc_jit_location *loc,
4235 : : const char *asm_template,
4236 : : int num_goto_blocks,
4237 : : gcc_jit_block **goto_blocks,
4238 : : gcc_jit_block *fallthrough_block)
4239 : : {
4240 : 20 : RETURN_NULL_IF_NOT_VALID_BLOCK (block, loc);
4241 : 20 : gcc::jit::recording::context *ctxt = block->get_context ();
4242 : 20 : JIT_LOG_FUNC (ctxt->get_logger ());
4243 : : /* LOC can be NULL. */
4244 : 20 : RETURN_NULL_IF_FAIL (asm_template, ctxt, loc, "NULL asm_template");
4245 : 20 : RETURN_NULL_IF_FAIL (num_goto_blocks >= 0, ctxt, loc, "num_goto_blocks < 0");
4246 : 40 : for (int i = 0; i < num_goto_blocks; i++)
4247 : 20 : RETURN_NULL_IF_FAIL_PRINTF1 (goto_blocks[i],
4248 : : ctxt, loc,
4249 : : "NULL goto_blocks[%i]", i);
4250 : : /* fallthrough_block can be NULL. */
4251 : 20 : return (gcc_jit_extended_asm *)block->end_with_extended_asm_goto
4252 : 20 : (loc, asm_template,
4253 : : num_goto_blocks, (gcc::jit::recording::block **)goto_blocks,
4254 : 20 : fallthrough_block);
4255 : 20 : }
4256 : :
4257 : : /* Public entrypoint. See description in libgccjit.h.
4258 : :
4259 : : After error-checking, this calls the trivial
4260 : : gcc::jit::recording::memento::as_object method (an extended_asm is a
4261 : : memento), in jit-recording.h. */
4262 : :
4263 : : gcc_jit_object *
4264 : 60 : gcc_jit_extended_asm_as_object (gcc_jit_extended_asm *ext_asm)
4265 : : {
4266 : 60 : RETURN_NULL_IF_FAIL (ext_asm, NULL, NULL, "NULL ext_asm");
4267 : :
4268 : 60 : return static_cast <gcc_jit_object *> (ext_asm->as_object ());
4269 : : }
4270 : :
4271 : : /* Public entrypoint. See description in libgccjit.h.
4272 : :
4273 : : After error-checking, the real work is done by the
4274 : : gcc::jit::recording::extended_asm::set_volatile_flag, in
4275 : : jit-recording.cc. */
4276 : :
4277 : : void
4278 : 20 : gcc_jit_extended_asm_set_volatile_flag (gcc_jit_extended_asm *ext_asm,
4279 : : int flag)
4280 : : {
4281 : 20 : RETURN_IF_FAIL (ext_asm, NULL, NULL, "NULL ext_asm");
4282 : 20 : ext_asm->set_volatile_flag (flag);
4283 : : }
4284 : :
4285 : : /* Public entrypoint. See description in libgccjit.h.
4286 : :
4287 : : After error-checking, the real work is done by the
4288 : : gcc::jit::recording::extended_asm::set_inline_flag, in
4289 : : jit-recording.cc. */
4290 : :
4291 : : void
4292 : 0 : gcc_jit_extended_asm_set_inline_flag (gcc_jit_extended_asm *ext_asm,
4293 : : int flag)
4294 : : {
4295 : 0 : RETURN_IF_FAIL (ext_asm, NULL, NULL, "NULL ext_asm");
4296 : 0 : ext_asm->set_inline_flag (flag);
4297 : : }
4298 : :
4299 : : /* Public entrypoint. See description in libgccjit.h.
4300 : :
4301 : : After error-checking, the real work is done by the
4302 : : gcc::jit::recording::extended_asm::add_output_operand, in
4303 : : jit-recording.cc. */
4304 : :
4305 : : void
4306 : 40 : gcc_jit_extended_asm_add_output_operand (gcc_jit_extended_asm *ext_asm,
4307 : : const char *asm_symbolic_name,
4308 : : const char *constraint,
4309 : : gcc_jit_lvalue *dest)
4310 : : {
4311 : 40 : RETURN_IF_FAIL (ext_asm, NULL, NULL, "NULL ext_asm");
4312 : 40 : gcc::jit::recording::context *ctxt = ext_asm->get_context ();
4313 : 40 : JIT_LOG_FUNC (ctxt->get_logger ());
4314 : 40 : gcc::jit::recording::location *loc = ext_asm->get_loc ();
4315 : : /* asm_symbolic_name can be NULL. */
4316 : 40 : RETURN_IF_FAIL (constraint, ctxt, loc, "NULL constraint");
4317 : 40 : RETURN_IF_FAIL (dest, ctxt, loc, "NULL dest");
4318 : 40 : RETURN_IF_FAIL (!ext_asm->is_goto (), ctxt, loc,
4319 : : "cannot add output operand to asm goto");
4320 : 40 : ext_asm->add_output_operand (asm_symbolic_name, constraint, dest);
4321 : 40 : }
4322 : :
4323 : : /* Public entrypoint. See description in libgccjit.h.
4324 : :
4325 : : After error-checking, the real work is done by the
4326 : : gcc::jit::recording::extended_asm::add_input_operand, in
4327 : : jit-recording.cc. */
4328 : :
4329 : : extern void
4330 : 60 : gcc_jit_extended_asm_add_input_operand (gcc_jit_extended_asm *ext_asm,
4331 : : const char *asm_symbolic_name,
4332 : : const char *constraint,
4333 : : gcc_jit_rvalue *src)
4334 : : {
4335 : 60 : RETURN_IF_FAIL (ext_asm, NULL, NULL, "NULL ext_asm");
4336 : 60 : gcc::jit::recording::context *ctxt = ext_asm->get_context ();
4337 : 60 : JIT_LOG_FUNC (ctxt->get_logger ());
4338 : 60 : gcc::jit::recording::location *loc = ext_asm->get_loc ();
4339 : : /* asm_symbolic_name can be NULL. */
4340 : 60 : RETURN_IF_FAIL (constraint, ctxt, loc, "NULL constraint");
4341 : 60 : RETURN_IF_FAIL (src, ctxt, loc, "NULL src");
4342 : 60 : ext_asm->add_input_operand (asm_symbolic_name, constraint, src);
4343 : 60 : }
4344 : :
4345 : : /* Public entrypoint. See description in libgccjit.h.
4346 : :
4347 : : After error-checking, the real work is done by the
4348 : : gcc::jit::recording::extended_asm::add_clobber, in
4349 : : jit-recording.cc. */
4350 : :
4351 : : void
4352 : 50 : gcc_jit_extended_asm_add_clobber (gcc_jit_extended_asm *ext_asm,
4353 : : const char *victim)
4354 : : {
4355 : 50 : RETURN_IF_FAIL (ext_asm, NULL, NULL, "NULL ext_asm");
4356 : 50 : gcc::jit::recording::context *ctxt = ext_asm->get_context ();
4357 : 50 : JIT_LOG_FUNC (ctxt->get_logger ());
4358 : 50 : gcc::jit::recording::location *loc = ext_asm->get_loc ();
4359 : 50 : RETURN_IF_FAIL (victim, ctxt, loc, "NULL victim");
4360 : 50 : ext_asm->add_clobber (victim);
4361 : 50 : }
4362 : :
4363 : : /* Public entrypoint. See description in libgccjit.h.
4364 : :
4365 : : After error-checking, the real work is done by the
4366 : : gcc::jit::recording::context::add_top_level_asm, in
4367 : : jit-recording.cc. */
4368 : :
4369 : : void
4370 : 10 : gcc_jit_context_add_top_level_asm (gcc_jit_context *ctxt,
4371 : : gcc_jit_location *loc,
4372 : : const char *asm_stmts)
4373 : : {
4374 : 10 : RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL ctxt");
4375 : 10 : JIT_LOG_FUNC (ctxt->get_logger ());
4376 : : /* LOC can be NULL. */
4377 : 10 : RETURN_IF_FAIL (asm_stmts, ctxt, NULL, "NULL asm_stmts");
4378 : 10 : ctxt->add_top_level_asm (loc, asm_stmts);
4379 : 10 : }
|