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