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