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