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