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