1 /* Implementation of the C API; all wrappers into the internal C++ API
2 Copyright (C) 2013-2020 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 #include "system.h"
23 #include "coretypes.h"
24 #include "timevar.h"
25 #include "typed-splay-tree.h"
26 #include "cppbuiltin.h"
27 #include <pthread.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 struct gcc_jit_context : public gcc::jit::recording::context
37 {
gcc_jit_contextgcc_jit_context38 gcc_jit_context (gcc_jit_context *parent_ctxt) :
39 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_field : public gcc::jit::recording::field
64 {
65 };
66
67 struct gcc_jit_bitfield : public gcc::jit::recording::bitfield
68 {
69 };
70
71 struct gcc_jit_function : public gcc::jit::recording::function
72 {
73 };
74
75 struct gcc_jit_block : public gcc::jit::recording::block
76 {
77 };
78
79 struct gcc_jit_rvalue : public gcc::jit::recording::rvalue
80 {
81 };
82
83 struct gcc_jit_lvalue : public gcc::jit::recording::lvalue
84 {
85 };
86
87 struct gcc_jit_param : public gcc::jit::recording::param
88 {
89 };
90
91 struct gcc_jit_case : public gcc::jit::recording::case_
92 {
93 };
94
95 struct gcc_jit_timer : public timer
96 {
97 };
98
99 /**********************************************************************
100 Error-handling.
101
102 We try to gracefully handle API usage errors by being defensive
103 at the API boundary.
104 **********************************************************************/
105
106 #define JIT_BEGIN_STMT do {
107 #define JIT_END_STMT } while(0)
108
109 /* Each of these error-handling macros determines if TEST_EXPR holds.
110
111 If TEXT_EXPR fails to hold we return from the enclosing function and
112 print an error, either via adding an error on the given context CTXT
113 if CTXT is non-NULL, falling back to simply printing to stderr if CTXT
114 is NULL.
115
116 They have to be macros since they inject their "return" into the
117 function they are placed in.
118
119 The variant macros express:
120
121 (A) whether or not we need to return a value:
122 RETURN_VAL_IF_FAIL* vs
123 RETURN_IF_FAIL*,
124 with the former returning RETURN_EXPR, and
125 RETURN_NULL_IF_FAIL*
126 for the common case where a NULL value is to be returned on
127 error, and
128
129 (B) whether the error message is to be directly printed:
130 RETURN_*IF_FAIL
131 or is a format string with some number of arguments:
132 RETURN_*IF_FAIL_PRINTF*
133
134 They all use JIT_BEGIN_STMT/JIT_END_STMT so they can be written with
135 trailing semicolons.
136 */
137
138 #define RETURN_VAL_IF_FAIL(TEST_EXPR, RETURN_EXPR, CTXT, LOC, ERR_MSG) \
139 JIT_BEGIN_STMT \
140 if (!(TEST_EXPR)) \
141 { \
142 jit_error ((CTXT), (LOC), "%s: %s", __func__, (ERR_MSG)); \
143 return (RETURN_EXPR); \
144 } \
145 JIT_END_STMT
146
147 #define RETURN_VAL_IF_FAIL_PRINTF1(TEST_EXPR, RETURN_EXPR, CTXT, LOC, ERR_FMT, A0) \
148 JIT_BEGIN_STMT \
149 if (!(TEST_EXPR)) \
150 { \
151 jit_error ((CTXT), (LOC), "%s: " ERR_FMT, \
152 __func__, (A0)); \
153 return (RETURN_EXPR); \
154 } \
155 JIT_END_STMT
156
157 #define RETURN_VAL_IF_FAIL_PRINTF2(TEST_EXPR, RETURN_EXPR, CTXT, LOC, ERR_FMT, A0, A1) \
158 JIT_BEGIN_STMT \
159 if (!(TEST_EXPR)) \
160 { \
161 jit_error ((CTXT), (LOC), "%s: " ERR_FMT, \
162 __func__, (A0), (A1)); \
163 return (RETURN_EXPR); \
164 } \
165 JIT_END_STMT
166
167 #define RETURN_VAL_IF_FAIL_PRINTF3(TEST_EXPR, RETURN_EXPR, CTXT, LOC, ERR_FMT, A0, A1, A2) \
168 JIT_BEGIN_STMT \
169 if (!(TEST_EXPR)) \
170 { \
171 jit_error ((CTXT), (LOC), "%s: " ERR_FMT, \
172 __func__, (A0), (A1), (A2)); \
173 return (RETURN_EXPR); \
174 } \
175 JIT_END_STMT
176
177 #define RETURN_VAL_IF_FAIL_PRINTF4(TEST_EXPR, RETURN_EXPR, CTXT, LOC, ERR_FMT, A0, A1, A2, A3) \
178 JIT_BEGIN_STMT \
179 if (!(TEST_EXPR)) \
180 { \
181 jit_error ((CTXT), (LOC), "%s: " ERR_FMT, \
182 __func__, (A0), (A1), (A2), (A3)); \
183 return (RETURN_EXPR); \
184 } \
185 JIT_END_STMT
186
187 #define RETURN_VAL_IF_FAIL_PRINTF5(TEST_EXPR, RETURN_EXPR, CTXT, LOC, ERR_FMT, A0, A1, A2, A3, A4) \
188 JIT_BEGIN_STMT \
189 if (!(TEST_EXPR)) \
190 { \
191 jit_error ((CTXT), (LOC), "%s: " ERR_FMT, \
192 __func__, (A0), (A1), (A2), (A3), (A4)); \
193 return (RETURN_EXPR); \
194 } \
195 JIT_END_STMT
196
197 #define RETURN_VAL_IF_FAIL_PRINTF6(TEST_EXPR, RETURN_EXPR, CTXT, LOC, ERR_FMT, A0, A1, A2, A3, A4, A5) \
198 JIT_BEGIN_STMT \
199 if (!(TEST_EXPR)) \
200 { \
201 jit_error ((CTXT), (LOC), "%s: " ERR_FMT, \
202 __func__, (A0), (A1), (A2), (A3), (A4), (A5)); \
203 return (RETURN_EXPR); \
204 } \
205 JIT_END_STMT
206
207 #define RETURN_NULL_IF_FAIL(TEST_EXPR, CTXT, LOC, ERR_MSG) \
208 RETURN_VAL_IF_FAIL ((TEST_EXPR), NULL, (CTXT), (LOC), (ERR_MSG))
209
210 #define RETURN_NULL_IF_FAIL_PRINTF1(TEST_EXPR, CTXT, LOC, ERR_FMT, A0) \
211 RETURN_VAL_IF_FAIL_PRINTF1 (TEST_EXPR, NULL, CTXT, LOC, ERR_FMT, A0)
212
213 #define RETURN_NULL_IF_FAIL_PRINTF2(TEST_EXPR, CTXT, LOC, ERR_FMT, A0, A1) \
214 RETURN_VAL_IF_FAIL_PRINTF2 (TEST_EXPR, NULL, CTXT, LOC, ERR_FMT, A0, A1)
215
216 #define RETURN_NULL_IF_FAIL_PRINTF3(TEST_EXPR, CTXT, LOC, ERR_FMT, A0, A1, A2) \
217 RETURN_VAL_IF_FAIL_PRINTF3 (TEST_EXPR, NULL, CTXT, LOC, ERR_FMT, A0, A1, A2)
218
219 #define RETURN_NULL_IF_FAIL_PRINTF4(TEST_EXPR, CTXT, LOC, ERR_FMT, A0, A1, A2, A3) \
220 RETURN_VAL_IF_FAIL_PRINTF4 (TEST_EXPR, NULL, CTXT, LOC, ERR_FMT, A0, A1, A2, A3)
221
222 #define RETURN_NULL_IF_FAIL_PRINTF5(TEST_EXPR, CTXT, LOC, ERR_FMT, A0, A1, A2, A3, A4) \
223 RETURN_VAL_IF_FAIL_PRINTF5 (TEST_EXPR, NULL, CTXT, LOC, ERR_FMT, A0, A1, A2, A3, A4)
224
225 #define RETURN_NULL_IF_FAIL_PRINTF6(TEST_EXPR, CTXT, LOC, ERR_FMT, A0, A1, A2, A3, A4, A5) \
226 RETURN_VAL_IF_FAIL_PRINTF6 (TEST_EXPR, NULL, CTXT, LOC, ERR_FMT, A0, A1, A2, A3, A4, A5)
227
228 #define RETURN_IF_FAIL(TEST_EXPR, CTXT, LOC, ERR_MSG) \
229 JIT_BEGIN_STMT \
230 if (!(TEST_EXPR)) \
231 { \
232 jit_error ((CTXT), (LOC), "%s: %s", __func__, (ERR_MSG)); \
233 return; \
234 } \
235 JIT_END_STMT
236
237 #define RETURN_IF_FAIL_PRINTF1(TEST_EXPR, CTXT, LOC, ERR_FMT, A0) \
238 JIT_BEGIN_STMT \
239 if (!(TEST_EXPR)) \
240 { \
241 jit_error ((CTXT), (LOC), "%s: " ERR_FMT, \
242 __func__, (A0)); \
243 return; \
244 } \
245 JIT_END_STMT
246
247 #define RETURN_IF_FAIL_PRINTF2(TEST_EXPR, CTXT, LOC, ERR_FMT, A0, A1) \
248 JIT_BEGIN_STMT \
249 if (!(TEST_EXPR)) \
250 { \
251 jit_error ((CTXT), (LOC), "%s: " ERR_FMT, \
252 __func__, (A0), (A1)); \
253 return; \
254 } \
255 JIT_END_STMT
256
257 #define RETURN_IF_FAIL_PRINTF4(TEST_EXPR, CTXT, LOC, ERR_FMT, A0, A1, A2, A3) \
258 JIT_BEGIN_STMT \
259 if (!(TEST_EXPR)) \
260 { \
261 jit_error ((CTXT), (LOC), "%s: " ERR_FMT, \
262 __func__, (A0), (A1), (A2), (A3)); \
263 return; \
264 } \
265 JIT_END_STMT
266
267 /* Check that BLOCK is non-NULL, and that it's OK to add statements to
268 it. This will fail if BLOCK has already been terminated by some
269 kind of jump or a return. */
270 #define RETURN_IF_NOT_VALID_BLOCK(BLOCK, LOC) \
271 JIT_BEGIN_STMT \
272 RETURN_IF_FAIL ((BLOCK), NULL, (LOC), "NULL block"); \
273 RETURN_IF_FAIL_PRINTF2 ( \
274 !(BLOCK)->has_been_terminated (), \
275 (BLOCK)->get_context (), \
276 (LOC), \
277 "adding to terminated block: %s (already terminated by: %s)", \
278 (BLOCK)->get_debug_string (), \
279 (BLOCK)->get_last_statement ()->get_debug_string ()); \
280 JIT_END_STMT
281
282 /* As RETURN_IF_NOT_VALID_BLOCK, but injecting a "return NULL;" if it
283 fails. */
284 #define RETURN_NULL_IF_NOT_VALID_BLOCK(BLOCK, LOC) \
285 JIT_BEGIN_STMT \
286 RETURN_NULL_IF_FAIL ((BLOCK), NULL, (LOC), "NULL block"); \
287 RETURN_NULL_IF_FAIL_PRINTF2 ( \
288 !(BLOCK)->has_been_terminated (), \
289 (BLOCK)->get_context (), \
290 (LOC), \
291 "adding to terminated block: %s (already terminated by: %s)", \
292 (BLOCK)->get_debug_string (), \
293 (BLOCK)->get_last_statement ()->get_debug_string ()); \
294 JIT_END_STMT
295
296 /* Format the given string, and report it as an error, either on CTXT
297 if non-NULL, or by printing to stderr if we have a NULL context.
298 LOC gives the source location where the error occcurred, and can be
299 NULL. */
300
301 static void
302 jit_error (gcc::jit::recording::context *ctxt,
303 gcc_jit_location *loc,
304 const char *fmt, ...)
305 GNU_PRINTF(3, 4);
306
307 static void
jit_error(gcc::jit::recording::context * ctxt,gcc_jit_location * loc,const char * fmt,...)308 jit_error (gcc::jit::recording::context *ctxt,
309 gcc_jit_location *loc,
310 const char *fmt, ...)
311 {
312 va_list ap;
313 va_start (ap, fmt);
314
315 if (ctxt)
316 ctxt->add_error_va (loc, fmt, ap);
317 else
318 {
319 /* No context? Send to stderr. */
320 vfprintf (stderr, fmt, ap);
321 fprintf (stderr, "\n");
322 }
323
324 va_end (ap);
325 }
326
327 /* Determine whether or not we can write to lvalues of type LTYPE from
328 rvalues of type RTYPE, detecting type errors such as attempting to
329 write to an int with a string literal (without an explicit cast).
330
331 This is implemented by calling the
332 gcc::jit::recording::type::accepts_writes_from virtual function on
333 LTYPE. */
334
335 static bool
compatible_types(gcc::jit::recording::type * ltype,gcc::jit::recording::type * rtype)336 compatible_types (gcc::jit::recording::type *ltype,
337 gcc::jit::recording::type *rtype)
338 {
339 return ltype->accepts_writes_from (rtype);
340 }
341
342 /* Public entrypoint for acquiring a gcc_jit_context.
343 Note that this creates a new top-level context; contrast with
344 gcc_jit_context_new_child_context below.
345
346 The real work is done in the constructor for
347 gcc::jit::recording::context in jit-recording.c. */
348
349 gcc_jit_context *
gcc_jit_context_acquire(void)350 gcc_jit_context_acquire (void)
351 {
352 gcc_jit_context *ctxt = new gcc_jit_context (NULL);
353 ctxt->log ("new top-level ctxt: %p", (void *)ctxt);
354 return ctxt;
355 }
356
357 /* Public entrypoint for releasing a gcc_jit_context.
358 The real work is done in the destructor for
359 gcc::jit::recording::context in jit-recording.c. */
360
361 void
gcc_jit_context_release(gcc_jit_context * ctxt)362 gcc_jit_context_release (gcc_jit_context *ctxt)
363 {
364 RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL ctxt");
365 JIT_LOG_FUNC (ctxt->get_logger ());
366 ctxt->log ("deleting ctxt: %p", (void *)ctxt);
367 delete ctxt;
368 }
369
370 /* Public entrypoint for creating a child context within
371 PARENT_CTXT. See description in libgccjit.h.
372
373 The real work is done in the constructor for
374 gcc::jit::recording::context in jit-recording.c. */
375
376 gcc_jit_context *
gcc_jit_context_new_child_context(gcc_jit_context * parent_ctxt)377 gcc_jit_context_new_child_context (gcc_jit_context *parent_ctxt)
378 {
379 RETURN_NULL_IF_FAIL (parent_ctxt, NULL, NULL, "NULL parent ctxt");
380 JIT_LOG_FUNC (parent_ctxt->get_logger ());
381 parent_ctxt->log ("parent_ctxt: %p", (void *)parent_ctxt);
382 gcc_jit_context *child_ctxt = new gcc_jit_context (parent_ctxt);
383 child_ctxt->log ("new child_ctxt: %p", (void *)child_ctxt);
384 return child_ctxt;
385 }
386
387 /* Public entrypoint. See description in libgccjit.h.
388
389 After error-checking, the real work is done by the
390 gcc::jit::recording::context::new_location
391 method in jit-recording.c. */
392
393 gcc_jit_location *
gcc_jit_context_new_location(gcc_jit_context * ctxt,const char * filename,int line,int column)394 gcc_jit_context_new_location (gcc_jit_context *ctxt,
395 const char *filename,
396 int line,
397 int column)
398 {
399 RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
400 JIT_LOG_FUNC (ctxt->get_logger ());
401 return (gcc_jit_location *)ctxt->new_location (filename, line, column, true);
402 }
403
404 /* Public entrypoint. See description in libgccjit.h.
405
406 After error-checking, this calls the trivial
407 gcc::jit::recording::memento::as_object method (a location is a
408 memento), in jit-recording.h. */
409
410 gcc_jit_object *
gcc_jit_location_as_object(gcc_jit_location * loc)411 gcc_jit_location_as_object (gcc_jit_location *loc)
412 {
413 RETURN_NULL_IF_FAIL (loc, NULL, NULL, "NULL location");
414
415 return static_cast <gcc_jit_object *> (loc->as_object ());
416 }
417
418 /* Public entrypoint. See description in libgccjit.h.
419
420 After error-checking, this calls the trivial
421 gcc::jit::recording::memento::as_object method (a type is a
422 memento), in jit-recording.h. */
423
424 gcc_jit_object *
gcc_jit_type_as_object(gcc_jit_type * type)425 gcc_jit_type_as_object (gcc_jit_type *type)
426 {
427 RETURN_NULL_IF_FAIL (type, NULL, NULL, "NULL type");
428
429 return static_cast <gcc_jit_object *> (type->as_object ());
430 }
431
432 /* Public entrypoint for getting a specific type from a context.
433
434 After error-checking, the real work is done by the
435 gcc::jit::recording::context::get_type method, in
436 jit-recording.c */
437
438 gcc_jit_type *
gcc_jit_context_get_type(gcc_jit_context * ctxt,enum gcc_jit_types type)439 gcc_jit_context_get_type (gcc_jit_context *ctxt,
440 enum gcc_jit_types type)
441 {
442 RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
443 JIT_LOG_FUNC (ctxt->get_logger ());
444 RETURN_NULL_IF_FAIL_PRINTF1 (
445 (type >= GCC_JIT_TYPE_VOID
446 && type <= GCC_JIT_TYPE_FILE_PTR),
447 ctxt, NULL,
448 "unrecognized value for enum gcc_jit_types: %i", type);
449
450 return (gcc_jit_type *)ctxt->get_type (type);
451 }
452
453 /* Public entrypoint for getting the integer type of the given size and
454 signedness.
455
456 After error-checking, the real work is done by the
457 gcc::jit::recording::context::get_int_type method,
458 in jit-recording.c. */
459
460 gcc_jit_type *
gcc_jit_context_get_int_type(gcc_jit_context * ctxt,int num_bytes,int is_signed)461 gcc_jit_context_get_int_type (gcc_jit_context *ctxt,
462 int num_bytes, int is_signed)
463 {
464 RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
465 JIT_LOG_FUNC (ctxt->get_logger ());
466 RETURN_NULL_IF_FAIL (num_bytes >= 0, ctxt, NULL, "negative size");
467
468 return (gcc_jit_type *)ctxt->get_int_type (num_bytes, is_signed);
469 }
470
471 /* Public entrypoint. See description in libgccjit.h.
472
473 After error-checking, the real work is done by the
474 gcc::jit::recording::type::get_pointer method, in
475 jit-recording.c */
476
477 gcc_jit_type *
gcc_jit_type_get_pointer(gcc_jit_type * type)478 gcc_jit_type_get_pointer (gcc_jit_type *type)
479 {
480 RETURN_NULL_IF_FAIL (type, NULL, NULL, "NULL type");
481
482 return (gcc_jit_type *)type->get_pointer ();
483 }
484
485 /* Public entrypoint. See description in libgccjit.h.
486
487 After error-checking, the real work is done by the
488 gcc::jit::recording::type::get_const method, in
489 jit-recording.c. */
490
491 gcc_jit_type *
gcc_jit_type_get_const(gcc_jit_type * type)492 gcc_jit_type_get_const (gcc_jit_type *type)
493 {
494 RETURN_NULL_IF_FAIL (type, NULL, NULL, "NULL type");
495
496 return (gcc_jit_type *)type->get_const ();
497 }
498
499 /* Public entrypoint. See description in libgccjit.h.
500
501 After error-checking, the real work is done by the
502 gcc::jit::recording::type::get_volatile method, in
503 jit-recording.c. */
504
505 gcc_jit_type *
gcc_jit_type_get_volatile(gcc_jit_type * type)506 gcc_jit_type_get_volatile (gcc_jit_type *type)
507 {
508 RETURN_NULL_IF_FAIL (type, NULL, NULL, "NULL type");
509
510 return (gcc_jit_type *)type->get_volatile ();
511 }
512
513 /* Public entrypoint. See description in libgccjit.h.
514
515 After error-checking, the real work is done by the
516 gcc::jit::recording::context::new_array_type method, in
517 jit-recording.c. */
518
519 gcc_jit_type *
gcc_jit_context_new_array_type(gcc_jit_context * ctxt,gcc_jit_location * loc,gcc_jit_type * element_type,int num_elements)520 gcc_jit_context_new_array_type (gcc_jit_context *ctxt,
521 gcc_jit_location *loc,
522 gcc_jit_type *element_type,
523 int num_elements)
524 {
525 RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
526 JIT_LOG_FUNC (ctxt->get_logger ());
527 /* LOC can be NULL. */
528 RETURN_NULL_IF_FAIL (element_type, ctxt, loc, "NULL type");
529 RETURN_NULL_IF_FAIL (num_elements >= 0, ctxt, NULL, "negative size");
530
531 return (gcc_jit_type *)ctxt->new_array_type (loc,
532 element_type,
533 num_elements);
534 }
535
536 /* Public entrypoint. See description in libgccjit.h.
537
538 After error-checking, the real work is done by the
539 gcc::jit::recording::context::new_field method, in
540 jit-recording.c. */
541
542 gcc_jit_field *
gcc_jit_context_new_field(gcc_jit_context * ctxt,gcc_jit_location * loc,gcc_jit_type * type,const char * name)543 gcc_jit_context_new_field (gcc_jit_context *ctxt,
544 gcc_jit_location *loc,
545 gcc_jit_type *type,
546 const char *name)
547 {
548 RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
549 JIT_LOG_FUNC (ctxt->get_logger ());
550 /* LOC can be NULL. */
551 RETURN_NULL_IF_FAIL (type, ctxt, loc, "NULL type");
552 RETURN_NULL_IF_FAIL (name, ctxt, loc, "NULL name");
553 RETURN_NULL_IF_FAIL_PRINTF2 (
554 type->has_known_size (),
555 ctxt, loc,
556 "unknown size for field \"%s\" (type: %s)",
557 name,
558 type->get_debug_string ());
559
560 return (gcc_jit_field *)ctxt->new_field (loc, type, name);
561 }
562
563 /* Public entrypoint. See description in libgccjit.h.
564
565 After error-checking, the real work is done by the
566 gcc::jit::recording::context::new_bitfield method, in
567 jit-recording.c. */
568
569 gcc_jit_field *
gcc_jit_context_new_bitfield(gcc_jit_context * ctxt,gcc_jit_location * loc,gcc_jit_type * type,int width,const char * name)570 gcc_jit_context_new_bitfield (gcc_jit_context *ctxt,
571 gcc_jit_location *loc,
572 gcc_jit_type *type,
573 int width,
574 const char *name)
575 {
576 RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
577 JIT_LOG_FUNC (ctxt->get_logger ());
578 /* LOC can be NULL. */
579 RETURN_NULL_IF_FAIL (name, ctxt, loc, "NULL name");
580 RETURN_NULL_IF_FAIL (type, ctxt, loc, "NULL type");
581 RETURN_NULL_IF_FAIL_PRINTF2 (type->is_int () || type->is_bool (),
582 ctxt, loc,
583 "bit-field %s has non integral type %s",
584 name, type->get_debug_string ());
585 RETURN_NULL_IF_FAIL_PRINTF2 (
586 width > 0, ctxt, loc,
587 "invalid width %d for bitfield \"%s\" (must be > 0)",
588 width, name);
589 RETURN_NULL_IF_FAIL_PRINTF2 (
590 type->has_known_size (),
591 ctxt, loc,
592 "unknown size for field \"%s\" (type: %s)",
593 name,
594 type->get_debug_string ());
595
596 return (gcc_jit_field *)ctxt->new_bitfield (loc, type, width, name);
597 }
598
599 /* Public entrypoint. See description in libgccjit.h.
600
601 After error-checking, this calls the trivial
602 gcc::jit::recording::memento::as_object method (a field is a
603 memento), in jit-recording.h. */
604
605 gcc_jit_object *
gcc_jit_field_as_object(gcc_jit_field * field)606 gcc_jit_field_as_object (gcc_jit_field *field)
607 {
608 RETURN_NULL_IF_FAIL (field, NULL, NULL, "NULL field");
609
610 return static_cast <gcc_jit_object *> (field->as_object ());
611 }
612
613 /* Public entrypoint. See description in libgccjit.h.
614
615 After error-checking, the real work is done by the
616 gcc::jit::recording::context::new_struct_type method,
617 immediately followed by a "set_fields" call on the resulting
618 gcc::jit::recording::compound_type *, both in jit-recording.c */
619
620 gcc_jit_struct *
gcc_jit_context_new_struct_type(gcc_jit_context * ctxt,gcc_jit_location * loc,const char * name,int num_fields,gcc_jit_field ** fields)621 gcc_jit_context_new_struct_type (gcc_jit_context *ctxt,
622 gcc_jit_location *loc,
623 const char *name,
624 int num_fields,
625 gcc_jit_field **fields)
626 {
627 RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
628 JIT_LOG_FUNC (ctxt->get_logger ());
629 /* LOC can be NULL. */
630 RETURN_NULL_IF_FAIL (name, ctxt, loc, "NULL name");
631 if (num_fields)
632 RETURN_NULL_IF_FAIL (fields, ctxt, loc, "NULL fields ptr");
633 for (int i = 0; i < num_fields; i++)
634 {
635 RETURN_NULL_IF_FAIL (fields[i], ctxt, loc, "NULL field ptr");
636 RETURN_NULL_IF_FAIL_PRINTF2 (
637 fields[i]->get_container () == NULL,
638 ctxt, loc,
639 "%s is already a field of %s",
640 fields[i]->get_debug_string (),
641 fields[i]->get_container ()->get_debug_string ());
642 }
643
644 gcc::jit::recording::struct_ *result =
645 ctxt->new_struct_type (loc, name);
646 result->set_fields (loc,
647 num_fields,
648 (gcc::jit::recording::field **)fields);
649 return static_cast<gcc_jit_struct *> (result);
650 }
651
652 /* Public entrypoint. See description in libgccjit.h.
653
654 After error-checking, the real work is done by the
655 gcc::jit::recording::context::new_struct_type method in
656 jit-recording.c. */
657
658 gcc_jit_struct *
gcc_jit_context_new_opaque_struct(gcc_jit_context * ctxt,gcc_jit_location * loc,const char * name)659 gcc_jit_context_new_opaque_struct (gcc_jit_context *ctxt,
660 gcc_jit_location *loc,
661 const char *name)
662 {
663 RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
664 JIT_LOG_FUNC (ctxt->get_logger ());
665 /* LOC can be NULL. */
666 RETURN_NULL_IF_FAIL (name, ctxt, loc, "NULL name");
667
668 return (gcc_jit_struct *)ctxt->new_struct_type (loc, name);
669 }
670
671 /* Public entrypoint. See description in libgccjit.h.
672
673 After error-checking, this calls the trivial
674 gcc::jit::recording::struct_::as_object method in
675 jit-recording.h. */
676
677 gcc_jit_type *
gcc_jit_struct_as_type(gcc_jit_struct * struct_type)678 gcc_jit_struct_as_type (gcc_jit_struct *struct_type)
679 {
680 RETURN_NULL_IF_FAIL (struct_type, NULL, NULL, "NULL struct_type");
681
682 return static_cast <gcc_jit_type *> (struct_type->as_type ());
683 }
684
685 /* Public entrypoint. See description in libgccjit.h.
686
687 After error-checking, the real work is done by the
688 gcc::jit::recording::compound_type::set_fields method in
689 jit-recording.c. */
690
691 void
gcc_jit_struct_set_fields(gcc_jit_struct * struct_type,gcc_jit_location * loc,int num_fields,gcc_jit_field ** fields)692 gcc_jit_struct_set_fields (gcc_jit_struct *struct_type,
693 gcc_jit_location *loc,
694 int num_fields,
695 gcc_jit_field **fields)
696 {
697 RETURN_IF_FAIL (struct_type, NULL, loc, "NULL struct_type");
698 gcc::jit::recording::context *ctxt = struct_type->m_ctxt;
699 JIT_LOG_FUNC (ctxt->get_logger ());
700 /* LOC can be NULL. */
701 RETURN_IF_FAIL_PRINTF1 (
702 struct_type->get_fields () == NULL, ctxt, loc,
703 "%s already has had fields set",
704 struct_type->get_debug_string ());
705 if (num_fields)
706 RETURN_IF_FAIL (fields, ctxt, loc, "NULL fields ptr");
707 for (int i = 0; i < num_fields; i++)
708 {
709 RETURN_IF_FAIL_PRINTF2 (
710 fields[i],
711 ctxt, loc,
712 "%s: NULL field ptr at index %i",
713 struct_type->get_debug_string (),
714 i);
715 RETURN_IF_FAIL_PRINTF2 (
716 fields[i]->get_container () == NULL,
717 ctxt, loc,
718 "%s is already a field of %s",
719 fields[i]->get_debug_string (),
720 fields[i]->get_container ()->get_debug_string ());
721 }
722
723 struct_type->set_fields (loc, num_fields,
724 (gcc::jit::recording::field **)fields);
725 }
726
727 /* Public entrypoint. See description in libgccjit.h.
728
729 After error-checking, the real work is done by the
730 gcc::jit::recording::context::new_union_type method,
731 immediately followed by a "set_fields" call on the resulting
732 gcc::jit::recording::compound_type *, both in jit-recording.c */
733
734 gcc_jit_type *
gcc_jit_context_new_union_type(gcc_jit_context * ctxt,gcc_jit_location * loc,const char * name,int num_fields,gcc_jit_field ** fields)735 gcc_jit_context_new_union_type (gcc_jit_context *ctxt,
736 gcc_jit_location *loc,
737 const char *name,
738 int num_fields,
739 gcc_jit_field **fields)
740 {
741 RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
742 JIT_LOG_FUNC (ctxt->get_logger ());
743 /* LOC can be NULL. */
744 RETURN_NULL_IF_FAIL (name, ctxt, loc, "NULL name");
745 if (num_fields)
746 RETURN_NULL_IF_FAIL (fields, ctxt, loc, "NULL fields ptr");
747 for (int i = 0; i < num_fields; i++)
748 {
749 RETURN_NULL_IF_FAIL (fields[i], ctxt, loc, "NULL field ptr");
750 RETURN_NULL_IF_FAIL_PRINTF2 (
751 fields[i]->get_container () == NULL,
752 ctxt, loc,
753 "%s is already a field of %s",
754 fields[i]->get_debug_string (),
755 fields[i]->get_container ()->get_debug_string ());
756 }
757
758 gcc::jit::recording::union_ *result =
759 ctxt->new_union_type (loc, name);
760 result->set_fields (loc,
761 num_fields,
762 (gcc::jit::recording::field **)fields);
763 return (gcc_jit_type *) (result);
764 }
765
766 /* Public entrypoint. See description in libgccjit.h.
767
768 After error-checking, the real work is done by the
769 gcc::jit::recording::context::new_function_ptr_type method,
770 in jit-recording.c */
771
772 gcc_jit_type *
gcc_jit_context_new_function_ptr_type(gcc_jit_context * ctxt,gcc_jit_location * loc,gcc_jit_type * return_type,int num_params,gcc_jit_type ** param_types,int is_variadic)773 gcc_jit_context_new_function_ptr_type (gcc_jit_context *ctxt,
774 gcc_jit_location *loc,
775 gcc_jit_type *return_type,
776 int num_params,
777 gcc_jit_type **param_types,
778 int is_variadic)
779 {
780 RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
781 JIT_LOG_FUNC (ctxt->get_logger ());
782 /* LOC can be NULL. */
783 RETURN_NULL_IF_FAIL (return_type, ctxt, loc, "NULL return_type");
784 RETURN_NULL_IF_FAIL (
785 (num_params == 0) || param_types,
786 ctxt, loc,
787 "NULL param_types creating function pointer type");
788 for (int i = 0; i < num_params; i++)
789 RETURN_NULL_IF_FAIL_PRINTF1 (
790 param_types[i],
791 ctxt, loc,
792 "NULL parameter type %i creating function pointer type", i);
793
794 return (gcc_jit_type*)
795 ctxt->new_function_ptr_type (loc, return_type,
796 num_params,
797 (gcc::jit::recording::type **)param_types,
798 is_variadic);
799 }
800
801 /* Constructing functions. */
802
803 /* Public entrypoint. See description in libgccjit.h.
804
805 After error-checking, the real work is done by the
806 gcc::jit::recording::context::new_param method, in jit-recording.c */
807
808 gcc_jit_param *
gcc_jit_context_new_param(gcc_jit_context * ctxt,gcc_jit_location * loc,gcc_jit_type * type,const char * name)809 gcc_jit_context_new_param (gcc_jit_context *ctxt,
810 gcc_jit_location *loc,
811 gcc_jit_type *type,
812 const char *name)
813 {
814 RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
815 JIT_LOG_FUNC (ctxt->get_logger ());
816 /* LOC can be NULL. */
817 RETURN_NULL_IF_FAIL (type, ctxt, loc, "NULL type");
818 RETURN_NULL_IF_FAIL (name, ctxt, loc, "NULL name");
819
820 return (gcc_jit_param *)ctxt->new_param (loc, type, name);
821 }
822
823 /* Public entrypoint. See description in libgccjit.h.
824
825 After error-checking, this calls the trivial
826 gcc::jit::recording::memento::as_object method (a param is a memento),
827 in jit-recording.h. */
828
829 gcc_jit_object *
gcc_jit_param_as_object(gcc_jit_param * param)830 gcc_jit_param_as_object (gcc_jit_param *param)
831 {
832 RETURN_NULL_IF_FAIL (param, NULL, NULL, "NULL param");
833
834 return static_cast <gcc_jit_object *> (param->as_object ());
835 }
836
837 /* Public entrypoint. See description in libgccjit.h.
838
839 After error-checking, this calls the trivial
840 gcc::jit::recording::param::as_lvalue method in jit-recording.h. */
841
842 gcc_jit_lvalue *
gcc_jit_param_as_lvalue(gcc_jit_param * param)843 gcc_jit_param_as_lvalue (gcc_jit_param *param)
844 {
845 RETURN_NULL_IF_FAIL (param, NULL, NULL, "NULL param");
846
847 return (gcc_jit_lvalue *)param->as_lvalue ();
848 }
849
850 /* Public entrypoint. See description in libgccjit.h.
851
852 After error-checking, this calls the trivial
853 gcc::jit::recording::lvalue::as_rvalue method (a param is an rvalue),
854 in jit-recording.h. */
855
856 gcc_jit_rvalue *
gcc_jit_param_as_rvalue(gcc_jit_param * param)857 gcc_jit_param_as_rvalue (gcc_jit_param *param)
858 {
859 RETURN_NULL_IF_FAIL (param, NULL, NULL, "NULL param");
860
861 return (gcc_jit_rvalue *)param->as_rvalue ();
862 }
863
864 /* Public entrypoint. See description in libgccjit.h.
865
866 After error-checking, the real work is done by the
867 gcc::jit::recording::context::new_function method, in
868 jit-recording.c. */
869
870 gcc_jit_function *
gcc_jit_context_new_function(gcc_jit_context * ctxt,gcc_jit_location * loc,enum gcc_jit_function_kind kind,gcc_jit_type * return_type,const char * name,int num_params,gcc_jit_param ** params,int is_variadic)871 gcc_jit_context_new_function (gcc_jit_context *ctxt,
872 gcc_jit_location *loc,
873 enum gcc_jit_function_kind kind,
874 gcc_jit_type *return_type,
875 const char *name,
876 int num_params,
877 gcc_jit_param **params,
878 int is_variadic)
879 {
880 RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
881 JIT_LOG_FUNC (ctxt->get_logger ());
882 /* LOC can be NULL. */
883 RETURN_NULL_IF_FAIL_PRINTF1 (
884 ((kind >= GCC_JIT_FUNCTION_EXPORTED)
885 && (kind <= GCC_JIT_FUNCTION_ALWAYS_INLINE)),
886 ctxt, loc,
887 "unrecognized value for enum gcc_jit_function_kind: %i",
888 kind);
889 RETURN_NULL_IF_FAIL (return_type, ctxt, loc, "NULL return_type");
890 RETURN_NULL_IF_FAIL (name, ctxt, loc, "NULL name");
891 /* The assembler can only handle certain names, so for now, enforce
892 C's rules for identiers upon the name, using ISALPHA and ISALNUM
893 from safe-ctype.h to ignore the current locale.
894 Eventually we'll need some way to interact with e.g. C++ name
895 mangling. */
896 {
897 /* Leading char: */
898 char ch = *name;
899 RETURN_NULL_IF_FAIL_PRINTF2 (
900 ISALPHA (ch) || ch == '_',
901 ctxt, loc,
902 "name \"%s\" contains invalid character: '%c'",
903 name, ch);
904 /* Subsequent chars: */
905 for (const char *ptr = name + 1; (ch = *ptr); ptr++)
906 {
907 RETURN_NULL_IF_FAIL_PRINTF2 (
908 ISALNUM (ch) || ch == '_',
909 ctxt, loc,
910 "name \"%s\" contains invalid character: '%c'",
911 name, ch);
912 }
913 }
914 RETURN_NULL_IF_FAIL_PRINTF1 (
915 (num_params == 0) || params,
916 ctxt, loc,
917 "NULL params creating function %s", name);
918 for (int i = 0; i < num_params; i++)
919 {
920 RETURN_NULL_IF_FAIL_PRINTF2 (
921 params[i],
922 ctxt, loc,
923 "NULL parameter %i creating function %s", i, name);
924 RETURN_NULL_IF_FAIL_PRINTF5 (
925 params[i]->get_scope () == NULL,
926 ctxt, loc,
927 "parameter %i \"%s\""
928 " (type: %s)"
929 " for function %s"
930 " was already used for function %s",
931 i, params[i]->get_debug_string (),
932 params[i]->get_type ()->get_debug_string (),
933 name,
934 params[i]->get_scope ()->get_debug_string ());
935 }
936
937 return (gcc_jit_function*)
938 ctxt->new_function (loc, kind, return_type, name,
939 num_params,
940 (gcc::jit::recording::param **)params,
941 is_variadic,
942 BUILT_IN_NONE);
943 }
944
945 /* Public entrypoint. See description in libgccjit.h.
946
947 After error-checking, the real work is done by the
948 gcc::jit::recording::context::get_builtin_function method, in
949 jit-recording.c. */
950
951 gcc_jit_function *
gcc_jit_context_get_builtin_function(gcc_jit_context * ctxt,const char * name)952 gcc_jit_context_get_builtin_function (gcc_jit_context *ctxt,
953 const char *name)
954 {
955 RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
956 JIT_LOG_FUNC (ctxt->get_logger ());
957 RETURN_NULL_IF_FAIL (name, ctxt, NULL, "NULL name");
958
959 return static_cast <gcc_jit_function *> (ctxt->get_builtin_function (name));
960 }
961
962 /* Public entrypoint. See description in libgccjit.h.
963
964 After error-checking, this calls the trivial
965 gcc::jit::recording::memento::as_object method (a function is a
966 memento), in jit-recording.h. */
967
968 gcc_jit_object *
gcc_jit_function_as_object(gcc_jit_function * func)969 gcc_jit_function_as_object (gcc_jit_function *func)
970 {
971 RETURN_NULL_IF_FAIL (func, NULL, NULL, "NULL function");
972
973 return static_cast <gcc_jit_object *> (func->as_object ());
974 }
975
976 /* Public entrypoint. See description in libgccjit.h.
977
978 After error-checking, the real work is done by the
979 gcc::jit::recording::function::get_param method, in
980 jit-recording.h. */
981
982 gcc_jit_param *
gcc_jit_function_get_param(gcc_jit_function * func,int index)983 gcc_jit_function_get_param (gcc_jit_function *func, int index)
984 {
985 RETURN_NULL_IF_FAIL (func, NULL, NULL, "NULL function");
986 gcc::jit::recording::context *ctxt = func->m_ctxt;
987 JIT_LOG_FUNC (ctxt->get_logger ());
988 RETURN_NULL_IF_FAIL (index >= 0, ctxt, NULL, "negative index");
989 int num_params = func->get_params ().length ();
990 RETURN_NULL_IF_FAIL_PRINTF3 (index < num_params,
991 ctxt, NULL,
992 "index of %d is too large (%s has %d params)",
993 index,
994 func->get_debug_string (),
995 num_params);
996
997 return static_cast <gcc_jit_param *> (func->get_param (index));
998 }
999
1000 /* Public entrypoint. See description in libgccjit.h.
1001
1002 After error-checking, the real work is done by the
1003 gcc::jit::recording::function::dump_to_dot method, in
1004 jit-recording.c. */
1005
1006 void
gcc_jit_function_dump_to_dot(gcc_jit_function * func,const char * path)1007 gcc_jit_function_dump_to_dot (gcc_jit_function *func,
1008 const char *path)
1009 {
1010 RETURN_IF_FAIL (func, NULL, NULL, "NULL function");
1011 gcc::jit::recording::context *ctxt = func->m_ctxt;
1012 JIT_LOG_FUNC (ctxt->get_logger ());
1013 RETURN_IF_FAIL (path, ctxt, NULL, "NULL path");
1014
1015 func->dump_to_dot (path);
1016 }
1017
1018 /* Public entrypoint. See description in libgccjit.h.
1019
1020 After error-checking, the real work is done by the
1021 gcc::jit::recording::function::new_block method, in
1022 jit-recording.c. */
1023
1024 gcc_jit_block*
gcc_jit_function_new_block(gcc_jit_function * func,const char * name)1025 gcc_jit_function_new_block (gcc_jit_function *func,
1026 const char *name)
1027 {
1028 RETURN_NULL_IF_FAIL (func, NULL, NULL, "NULL function");
1029 JIT_LOG_FUNC (func->get_context ()->get_logger ());
1030 RETURN_NULL_IF_FAIL (func->get_kind () != GCC_JIT_FUNCTION_IMPORTED,
1031 func->get_context (), NULL,
1032 "cannot add block to an imported function");
1033 /* name can be NULL. */
1034
1035 return (gcc_jit_block *)func->new_block (name);
1036 }
1037
1038 /* Public entrypoint. See description in libgccjit.h.
1039
1040 After error-checking, this calls the trivial
1041 gcc::jit::recording::memento::as_object method (a block is a
1042 memento), in jit-recording.h. */
1043
1044 gcc_jit_object *
gcc_jit_block_as_object(gcc_jit_block * block)1045 gcc_jit_block_as_object (gcc_jit_block *block)
1046 {
1047 RETURN_NULL_IF_FAIL (block, NULL, NULL, "NULL block");
1048
1049 return static_cast <gcc_jit_object *> (block->as_object ());
1050 }
1051
1052 /* Public entrypoint. See description in libgccjit.h.
1053
1054 After error-checking, the real work is done by the
1055 gcc::jit::recording::block::get_function method, in
1056 jit-recording.h. */
1057
1058 gcc_jit_function *
gcc_jit_block_get_function(gcc_jit_block * block)1059 gcc_jit_block_get_function (gcc_jit_block *block)
1060 {
1061 RETURN_NULL_IF_FAIL (block, NULL, NULL, "NULL block");
1062
1063 return static_cast <gcc_jit_function *> (block->get_function ());
1064 }
1065
1066 /* Public entrypoint. See description in libgccjit.h.
1067
1068 After error-checking, the real work is done by the
1069 gcc::jit::recording::context::new_global method, in
1070 jit-recording.c. */
1071
1072 gcc_jit_lvalue *
gcc_jit_context_new_global(gcc_jit_context * ctxt,gcc_jit_location * loc,enum gcc_jit_global_kind kind,gcc_jit_type * type,const char * name)1073 gcc_jit_context_new_global (gcc_jit_context *ctxt,
1074 gcc_jit_location *loc,
1075 enum gcc_jit_global_kind kind,
1076 gcc_jit_type *type,
1077 const char *name)
1078 {
1079 RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
1080 JIT_LOG_FUNC (ctxt->get_logger ());
1081 /* LOC can be NULL. */
1082 RETURN_NULL_IF_FAIL_PRINTF1 (
1083 ((kind >= GCC_JIT_GLOBAL_EXPORTED)
1084 && (kind <= GCC_JIT_GLOBAL_IMPORTED)),
1085 ctxt, loc,
1086 "unrecognized value for enum gcc_jit_global_kind: %i",
1087 kind);
1088 RETURN_NULL_IF_FAIL (type, ctxt, loc, "NULL type");
1089 RETURN_NULL_IF_FAIL (name, ctxt, loc, "NULL name");
1090 RETURN_NULL_IF_FAIL_PRINTF2 (
1091 type->has_known_size (),
1092 ctxt, loc,
1093 "unknown size for global \"%s\" (type: %s)",
1094 name,
1095 type->get_debug_string ());
1096
1097 return (gcc_jit_lvalue *)ctxt->new_global (loc, kind, type, name);
1098 }
1099
1100 /* Public entrypoint. See description in libgccjit.h.
1101
1102 After error-checking, this calls the trivial
1103 gcc::jit::recording::memento::as_object method (an lvalue is a
1104 memento), in jit-recording.h. */
1105
1106 gcc_jit_object *
gcc_jit_lvalue_as_object(gcc_jit_lvalue * lvalue)1107 gcc_jit_lvalue_as_object (gcc_jit_lvalue *lvalue)
1108 {
1109 RETURN_NULL_IF_FAIL (lvalue, NULL, NULL, "NULL lvalue");
1110
1111 return static_cast <gcc_jit_object *> (lvalue->as_object ());
1112 }
1113
1114 /* Public entrypoint. See description in libgccjit.h.
1115
1116 After error-checking, this calls the trivial
1117 gcc::jit::recording::lvalue::as_rvalue method in jit-recording.h. */
1118
1119 gcc_jit_rvalue *
gcc_jit_lvalue_as_rvalue(gcc_jit_lvalue * lvalue)1120 gcc_jit_lvalue_as_rvalue (gcc_jit_lvalue *lvalue)
1121 {
1122 RETURN_NULL_IF_FAIL (lvalue, NULL, NULL, "NULL lvalue");
1123
1124 return (gcc_jit_rvalue *)lvalue->as_rvalue ();
1125 }
1126
1127 /* Public entrypoint. See description in libgccjit.h.
1128
1129 After error-checking, this calls the trivial
1130 gcc::jit::recording::memento::as_object method (an rvalue is a
1131 memento), in jit-recording.h. */
1132
1133 gcc_jit_object *
gcc_jit_rvalue_as_object(gcc_jit_rvalue * rvalue)1134 gcc_jit_rvalue_as_object (gcc_jit_rvalue *rvalue)
1135 {
1136 RETURN_NULL_IF_FAIL (rvalue, NULL, NULL, "NULL rvalue");
1137
1138 return static_cast <gcc_jit_object *> (rvalue->as_object ());
1139 }
1140
1141 /* Public entrypoint. See description in libgccjit.h.
1142
1143 After error-checking, the real work is done by the
1144 gcc::jit::recording::rvalue::get_type method, in
1145 jit-recording.h. */
1146
1147 gcc_jit_type *
gcc_jit_rvalue_get_type(gcc_jit_rvalue * rvalue)1148 gcc_jit_rvalue_get_type (gcc_jit_rvalue *rvalue)
1149 {
1150 RETURN_NULL_IF_FAIL (rvalue, NULL, NULL, "NULL rvalue");
1151
1152 return static_cast <gcc_jit_type *> (rvalue->get_type ());
1153 }
1154
1155 /* Verify that NUMERIC_TYPE is non-NULL, and that it is a "numeric"
1156 type i.e. it satisfies gcc::jit::type::is_numeric (), such as the
1157 result of gcc_jit_context_get_type (GCC_JIT_TYPE_INT). */
1158
1159 #define RETURN_NULL_IF_FAIL_NONNULL_NUMERIC_TYPE(CTXT, NUMERIC_TYPE) \
1160 JIT_BEGIN_STMT \
1161 RETURN_NULL_IF_FAIL (NUMERIC_TYPE, CTXT, NULL, "NULL type"); \
1162 RETURN_NULL_IF_FAIL_PRINTF1 ( \
1163 NUMERIC_TYPE->is_numeric (), ctxt, NULL, \
1164 "not a numeric type: %s", \
1165 NUMERIC_TYPE->get_debug_string ()); \
1166 JIT_END_STMT
1167
1168 /* Public entrypoint. See description in libgccjit.h.
1169
1170 After error-checking, the real work is done by the
1171 gcc::jit::recording::context::new_rvalue_from_int method in
1172 jit-recording.c. */
1173
1174 gcc_jit_rvalue *
gcc_jit_context_new_rvalue_from_int(gcc_jit_context * ctxt,gcc_jit_type * numeric_type,int value)1175 gcc_jit_context_new_rvalue_from_int (gcc_jit_context *ctxt,
1176 gcc_jit_type *numeric_type,
1177 int value)
1178 {
1179 RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
1180 JIT_LOG_FUNC (ctxt->get_logger ());
1181 RETURN_NULL_IF_FAIL_NONNULL_NUMERIC_TYPE (ctxt, numeric_type);
1182
1183 return ((gcc_jit_rvalue *)ctxt
1184 ->new_rvalue_from_const <int> (numeric_type, value));
1185 }
1186
1187 /* FIXME. */
1188
1189 gcc_jit_rvalue *
gcc_jit_context_new_rvalue_from_long(gcc_jit_context * ctxt,gcc_jit_type * numeric_type,long value)1190 gcc_jit_context_new_rvalue_from_long (gcc_jit_context *ctxt,
1191 gcc_jit_type *numeric_type,
1192 long value)
1193 {
1194 RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
1195 JIT_LOG_FUNC (ctxt->get_logger ());
1196 RETURN_NULL_IF_FAIL_NONNULL_NUMERIC_TYPE (ctxt, numeric_type);
1197
1198 return ((gcc_jit_rvalue *)ctxt
1199 ->new_rvalue_from_const <long> (numeric_type, value));
1200 }
1201
1202 /* Public entrypoint. See description in libgccjit.h.
1203
1204 This is essentially equivalent to:
1205 gcc_jit_context_new_rvalue_from_int (ctxt, numeric_type, 0);
1206 albeit with slightly different error messages if an error occurs. */
1207
1208 gcc_jit_rvalue *
gcc_jit_context_zero(gcc_jit_context * ctxt,gcc_jit_type * numeric_type)1209 gcc_jit_context_zero (gcc_jit_context *ctxt,
1210 gcc_jit_type *numeric_type)
1211 {
1212 RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
1213 JIT_LOG_FUNC (ctxt->get_logger ());
1214 RETURN_NULL_IF_FAIL_NONNULL_NUMERIC_TYPE (ctxt, numeric_type);
1215
1216 return gcc_jit_context_new_rvalue_from_int (ctxt, numeric_type, 0);
1217 }
1218
1219 /* Public entrypoint. See description in libgccjit.h.
1220
1221 This is essentially equivalent to:
1222 gcc_jit_context_new_rvalue_from_int (ctxt, numeric_type, 1);
1223 albeit with slightly different error messages if an error occurs. */
1224
1225 gcc_jit_rvalue *
gcc_jit_context_one(gcc_jit_context * ctxt,gcc_jit_type * numeric_type)1226 gcc_jit_context_one (gcc_jit_context *ctxt,
1227 gcc_jit_type *numeric_type)
1228 {
1229 RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
1230 JIT_LOG_FUNC (ctxt->get_logger ());
1231 RETURN_NULL_IF_FAIL_NONNULL_NUMERIC_TYPE (ctxt, numeric_type);
1232
1233 return gcc_jit_context_new_rvalue_from_int (ctxt, numeric_type, 1);
1234 }
1235
1236 /* Public entrypoint. See description in libgccjit.h.
1237
1238 After error-checking, the real work is done by the
1239 gcc::jit::recording::context::new_rvalue_from_double method in
1240 jit-recording.c. */
1241
1242 gcc_jit_rvalue *
gcc_jit_context_new_rvalue_from_double(gcc_jit_context * ctxt,gcc_jit_type * numeric_type,double value)1243 gcc_jit_context_new_rvalue_from_double (gcc_jit_context *ctxt,
1244 gcc_jit_type *numeric_type,
1245 double value)
1246 {
1247 RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
1248 JIT_LOG_FUNC (ctxt->get_logger ());
1249 RETURN_NULL_IF_FAIL_NONNULL_NUMERIC_TYPE (ctxt, numeric_type);
1250
1251 return ((gcc_jit_rvalue *)ctxt
1252 ->new_rvalue_from_const <double> (numeric_type, value));
1253 }
1254
1255 /* Public entrypoint. See description in libgccjit.h.
1256
1257 After error-checking, the real work is done by the
1258 gcc::jit::recording::context::new_rvalue_from_ptr method in
1259 jit-recording.c. */
1260
1261 gcc_jit_rvalue *
gcc_jit_context_new_rvalue_from_ptr(gcc_jit_context * ctxt,gcc_jit_type * pointer_type,void * value)1262 gcc_jit_context_new_rvalue_from_ptr (gcc_jit_context *ctxt,
1263 gcc_jit_type *pointer_type,
1264 void *value)
1265 {
1266 RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
1267 JIT_LOG_FUNC (ctxt->get_logger ());
1268 RETURN_NULL_IF_FAIL (pointer_type, ctxt, NULL, "NULL type");
1269 RETURN_NULL_IF_FAIL_PRINTF1 (
1270 pointer_type->is_pointer (),
1271 ctxt, NULL,
1272 "not a pointer type (type: %s)",
1273 pointer_type->get_debug_string ());
1274
1275 return ((gcc_jit_rvalue *)ctxt
1276 ->new_rvalue_from_const <void *> (pointer_type, value));
1277 }
1278
1279 /* Public entrypoint. See description in libgccjit.h.
1280
1281 This is essentially equivalent to:
1282 gcc_jit_context_new_rvalue_from_ptr (ctxt, pointer_type, NULL);
1283 albeit with slightly different error messages if an error occurs. */
1284
1285 gcc_jit_rvalue *
gcc_jit_context_null(gcc_jit_context * ctxt,gcc_jit_type * pointer_type)1286 gcc_jit_context_null (gcc_jit_context *ctxt,
1287 gcc_jit_type *pointer_type)
1288 {
1289 RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
1290 JIT_LOG_FUNC (ctxt->get_logger ());
1291 RETURN_NULL_IF_FAIL (pointer_type, ctxt, NULL, "NULL type");
1292 RETURN_NULL_IF_FAIL_PRINTF1 (
1293 pointer_type->is_pointer (),
1294 ctxt, NULL,
1295 "not a pointer type (type: %s)",
1296 pointer_type->get_debug_string ());
1297
1298 return gcc_jit_context_new_rvalue_from_ptr (ctxt, pointer_type, NULL);
1299 }
1300
1301 /* Public entrypoint. See description in libgccjit.h.
1302
1303 After error-checking, the real work is done by the
1304 gcc::jit::recording::context::new_string_literal method in
1305 jit-recording.c. */
1306
1307 gcc_jit_rvalue *
gcc_jit_context_new_string_literal(gcc_jit_context * ctxt,const char * value)1308 gcc_jit_context_new_string_literal (gcc_jit_context *ctxt,
1309 const char *value)
1310 {
1311 RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
1312 JIT_LOG_FUNC (ctxt->get_logger ());
1313 RETURN_NULL_IF_FAIL (value, ctxt, NULL, "NULL value");
1314
1315 return (gcc_jit_rvalue *)ctxt->new_string_literal (value);
1316 }
1317
1318 /* Public entrypoint. See description in libgccjit.h.
1319
1320 After error-checking, the real work is done by the
1321 gcc::jit::recording::context::new_unary_op method in
1322 jit-recording.c. */
1323
1324 gcc_jit_rvalue *
gcc_jit_context_new_unary_op(gcc_jit_context * ctxt,gcc_jit_location * loc,enum gcc_jit_unary_op op,gcc_jit_type * result_type,gcc_jit_rvalue * rvalue)1325 gcc_jit_context_new_unary_op (gcc_jit_context *ctxt,
1326 gcc_jit_location *loc,
1327 enum gcc_jit_unary_op op,
1328 gcc_jit_type *result_type,
1329 gcc_jit_rvalue *rvalue)
1330 {
1331 RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
1332 JIT_LOG_FUNC (ctxt->get_logger ());
1333 /* LOC can be NULL. */
1334 RETURN_NULL_IF_FAIL_PRINTF1 (
1335 (op >= GCC_JIT_UNARY_OP_MINUS
1336 && op <= GCC_JIT_UNARY_OP_ABS),
1337 ctxt, loc,
1338 "unrecognized value for enum gcc_jit_unary_op: %i",
1339 op);
1340 RETURN_NULL_IF_FAIL (result_type, ctxt, loc, "NULL result_type");
1341 RETURN_NULL_IF_FAIL_PRINTF3 (
1342 result_type->is_numeric (), ctxt, loc,
1343 "gcc_jit_unary_op %s with operand %s "
1344 "has non-numeric result_type: %s",
1345 gcc::jit::unary_op_reproducer_strings[op],
1346 rvalue->get_debug_string (),
1347 result_type->get_debug_string ());
1348 RETURN_NULL_IF_FAIL (rvalue, ctxt, loc, "NULL rvalue");
1349
1350 return (gcc_jit_rvalue *)ctxt->new_unary_op (loc, op, result_type, rvalue);
1351 }
1352
1353 /* Determine if OP is a valid value for enum gcc_jit_binary_op.
1354 For use by both gcc_jit_context_new_binary_op and
1355 gcc_jit_block_add_assignment_op. */
1356
1357 static bool
valid_binary_op_p(enum gcc_jit_binary_op op)1358 valid_binary_op_p (enum gcc_jit_binary_op op)
1359 {
1360 return (op >= GCC_JIT_BINARY_OP_PLUS
1361 && op <= GCC_JIT_BINARY_OP_RSHIFT);
1362 }
1363
1364 /* Public entrypoint. See description in libgccjit.h.
1365
1366 After error-checking, the real work is done by the
1367 gcc::jit::recording::context::new_binary_op method in
1368 jit-recording.c. */
1369
1370 gcc_jit_rvalue *
gcc_jit_context_new_binary_op(gcc_jit_context * ctxt,gcc_jit_location * loc,enum gcc_jit_binary_op op,gcc_jit_type * result_type,gcc_jit_rvalue * a,gcc_jit_rvalue * b)1371 gcc_jit_context_new_binary_op (gcc_jit_context *ctxt,
1372 gcc_jit_location *loc,
1373 enum gcc_jit_binary_op op,
1374 gcc_jit_type *result_type,
1375 gcc_jit_rvalue *a, gcc_jit_rvalue *b)
1376 {
1377 RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
1378 JIT_LOG_FUNC (ctxt->get_logger ());
1379 /* LOC can be NULL. */
1380 RETURN_NULL_IF_FAIL_PRINTF1 (
1381 valid_binary_op_p (op),
1382 ctxt, loc,
1383 "unrecognized value for enum gcc_jit_binary_op: %i",
1384 op);
1385 RETURN_NULL_IF_FAIL (result_type, ctxt, loc, "NULL result_type");
1386 RETURN_NULL_IF_FAIL (a, ctxt, loc, "NULL a");
1387 RETURN_NULL_IF_FAIL (b, ctxt, loc, "NULL b");
1388 RETURN_NULL_IF_FAIL_PRINTF4 (
1389 a->get_type ()->unqualified () == b->get_type ()->unqualified (),
1390 ctxt, loc,
1391 "mismatching types for binary op:"
1392 " a: %s (type: %s) b: %s (type: %s)",
1393 a->get_debug_string (),
1394 a->get_type ()->get_debug_string (),
1395 b->get_debug_string (),
1396 b->get_type ()->get_debug_string ());
1397 RETURN_NULL_IF_FAIL_PRINTF4 (
1398 result_type->is_numeric (), ctxt, loc,
1399 "gcc_jit_binary_op %s with operands a: %s b: %s "
1400 "has non-numeric result_type: %s",
1401 gcc::jit::binary_op_reproducer_strings[op],
1402 a->get_debug_string (), b->get_debug_string (),
1403 result_type->get_debug_string ());
1404
1405 return (gcc_jit_rvalue *)ctxt->new_binary_op (loc, op, result_type, a, b);
1406 }
1407
1408 /* Public entrypoint. See description in libgccjit.h.
1409
1410 After error-checking, the real work is done by the
1411 gcc::jit::recording::context::new_comparison method in
1412 jit-recording.c. */
1413
1414 gcc_jit_rvalue *
gcc_jit_context_new_comparison(gcc_jit_context * ctxt,gcc_jit_location * loc,enum gcc_jit_comparison op,gcc_jit_rvalue * a,gcc_jit_rvalue * b)1415 gcc_jit_context_new_comparison (gcc_jit_context *ctxt,
1416 gcc_jit_location *loc,
1417 enum gcc_jit_comparison op,
1418 gcc_jit_rvalue *a, gcc_jit_rvalue *b)
1419 {
1420 RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
1421 JIT_LOG_FUNC (ctxt->get_logger ());
1422 /* LOC can be NULL. */
1423 RETURN_NULL_IF_FAIL_PRINTF1 (
1424 (op >= GCC_JIT_COMPARISON_EQ
1425 && op <= GCC_JIT_COMPARISON_GE),
1426 ctxt, loc,
1427 "unrecognized value for enum gcc_jit_comparison: %i",
1428 op);
1429 RETURN_NULL_IF_FAIL (a, ctxt, loc, "NULL a");
1430 RETURN_NULL_IF_FAIL (b, ctxt, loc, "NULL b");
1431 RETURN_NULL_IF_FAIL_PRINTF4 (
1432 a->get_type ()->unqualified () == b->get_type ()->unqualified (),
1433 ctxt, loc,
1434 "mismatching types for comparison:"
1435 " a: %s (type: %s) b: %s (type: %s)",
1436 a->get_debug_string (),
1437 a->get_type ()->get_debug_string (),
1438 b->get_debug_string (),
1439 b->get_type ()->get_debug_string ());
1440
1441 return (gcc_jit_rvalue *)ctxt->new_comparison (loc, op, a, b);
1442 }
1443
1444 /* Public entrypoint. See description in libgccjit.h.
1445
1446 After error-checking, the real work is done by the
1447 gcc::jit::recording::context::new_call method in
1448 jit-recording.c. */
1449
1450 gcc_jit_rvalue *
gcc_jit_context_new_call(gcc_jit_context * ctxt,gcc_jit_location * loc,gcc_jit_function * func,int numargs,gcc_jit_rvalue ** args)1451 gcc_jit_context_new_call (gcc_jit_context *ctxt,
1452 gcc_jit_location *loc,
1453 gcc_jit_function *func,
1454 int numargs , gcc_jit_rvalue **args)
1455 {
1456 RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
1457 JIT_LOG_FUNC (ctxt->get_logger ());
1458 /* LOC can be NULL. */
1459 RETURN_NULL_IF_FAIL (func, ctxt, loc, "NULL function");
1460 if (numargs)
1461 RETURN_NULL_IF_FAIL (args, ctxt, loc, "NULL args");
1462
1463 int min_num_params = func->get_params ().length ();
1464 bool is_variadic = func->is_variadic ();
1465
1466 RETURN_NULL_IF_FAIL_PRINTF3 (
1467 numargs >= min_num_params,
1468 ctxt, loc,
1469 "not enough arguments to function \"%s\""
1470 " (got %i args, expected %i)",
1471 func->get_name ()->c_str (),
1472 numargs, min_num_params);
1473
1474 RETURN_NULL_IF_FAIL_PRINTF3 (
1475 (numargs == min_num_params || is_variadic),
1476 ctxt, loc,
1477 "too many arguments to function \"%s\""
1478 " (got %i args, expected %i)",
1479 func->get_name ()->c_str (),
1480 numargs, min_num_params);
1481
1482 for (int i = 0; i < min_num_params; i++)
1483 {
1484 gcc::jit::recording::param *param = func->get_param (i);
1485 gcc_jit_rvalue *arg = args[i];
1486
1487 RETURN_NULL_IF_FAIL_PRINTF4 (
1488 arg,
1489 ctxt, loc,
1490 "NULL argument %i to function \"%s\":"
1491 " param %s (type: %s)",
1492 i + 1,
1493 func->get_name ()->c_str (),
1494 param->get_debug_string (),
1495 param->get_type ()->get_debug_string ());
1496
1497 RETURN_NULL_IF_FAIL_PRINTF6 (
1498 compatible_types (param->get_type (),
1499 arg->get_type ()),
1500 ctxt, loc,
1501 "mismatching types for argument %d of function \"%s\":"
1502 " assignment to param %s (type: %s) from %s (type: %s)",
1503 i + 1,
1504 func->get_name ()->c_str (),
1505 param->get_debug_string (),
1506 param->get_type ()->get_debug_string (),
1507 arg->get_debug_string (),
1508 arg->get_type ()->get_debug_string ());
1509 }
1510
1511 return (gcc_jit_rvalue *)ctxt->new_call (loc,
1512 func,
1513 numargs,
1514 (gcc::jit::recording::rvalue **)args);
1515 }
1516
1517 /* Public entrypoint. See description in libgccjit.h.
1518
1519 After error-checking, the real work is done by the
1520 gcc::jit::recording::context::new_call_through_ptr method in
1521 jit-recording.c. */
1522
1523 gcc_jit_rvalue *
gcc_jit_context_new_call_through_ptr(gcc_jit_context * ctxt,gcc_jit_location * loc,gcc_jit_rvalue * fn_ptr,int numargs,gcc_jit_rvalue ** args)1524 gcc_jit_context_new_call_through_ptr (gcc_jit_context *ctxt,
1525 gcc_jit_location *loc,
1526 gcc_jit_rvalue *fn_ptr,
1527 int numargs, gcc_jit_rvalue **args)
1528 {
1529 RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
1530 JIT_LOG_FUNC (ctxt->get_logger ());
1531 /* LOC can be NULL. */
1532 RETURN_NULL_IF_FAIL (fn_ptr, ctxt, loc, "NULL fn_ptr");
1533 if (numargs)
1534 RETURN_NULL_IF_FAIL (args, ctxt, loc, "NULL args");
1535
1536 gcc::jit::recording::type *ptr_type = fn_ptr->get_type ()->dereference ();
1537 RETURN_NULL_IF_FAIL_PRINTF2 (
1538 ptr_type, ctxt, loc,
1539 "fn_ptr is not a ptr: %s"
1540 " type: %s",
1541 fn_ptr->get_debug_string (),
1542 fn_ptr->get_type ()->get_debug_string ());
1543
1544 gcc::jit::recording::function_type *fn_type =
1545 ptr_type->dyn_cast_function_type();
1546 RETURN_NULL_IF_FAIL_PRINTF2 (
1547 fn_type, ctxt, loc,
1548 "fn_ptr is not a function ptr: %s"
1549 " type: %s",
1550 fn_ptr->get_debug_string (),
1551 fn_ptr->get_type ()->get_debug_string ());
1552
1553 int min_num_params = fn_type->get_param_types ().length ();
1554 bool is_variadic = fn_type->is_variadic ();
1555
1556 RETURN_NULL_IF_FAIL_PRINTF3 (
1557 numargs >= min_num_params,
1558 ctxt, loc,
1559 "not enough arguments to fn_ptr: %s"
1560 " (got %i args, expected %i)",
1561 fn_ptr->get_debug_string (),
1562 numargs, min_num_params);
1563
1564 RETURN_NULL_IF_FAIL_PRINTF3 (
1565 (numargs == min_num_params || is_variadic),
1566 ctxt, loc,
1567 "too many arguments to fn_ptr: %s"
1568 " (got %i args, expected %i)",
1569 fn_ptr->get_debug_string (),
1570 numargs, min_num_params);
1571
1572 for (int i = 0; i < min_num_params; i++)
1573 {
1574 gcc::jit::recording::type *param_type = fn_type->get_param_types ()[i];
1575 gcc_jit_rvalue *arg = args[i];
1576
1577 RETURN_NULL_IF_FAIL_PRINTF3 (
1578 arg,
1579 ctxt, loc,
1580 "NULL argument %i to fn_ptr: %s"
1581 " (type: %s)",
1582 i + 1,
1583 fn_ptr->get_debug_string (),
1584 param_type->get_debug_string ());
1585
1586 RETURN_NULL_IF_FAIL_PRINTF6 (
1587 compatible_types (param_type,
1588 arg->get_type ()),
1589 ctxt, loc,
1590 "mismatching types for argument %d of fn_ptr: %s:"
1591 " assignment to param %d (type: %s) from %s (type: %s)",
1592 i + 1,
1593 fn_ptr->get_debug_string (),
1594 i + 1,
1595 param_type->get_debug_string (),
1596 arg->get_debug_string (),
1597 arg->get_type ()->get_debug_string ());
1598 }
1599
1600 return (gcc_jit_rvalue *)(
1601 ctxt->new_call_through_ptr (loc,
1602 fn_ptr,
1603 numargs,
1604 (gcc::jit::recording::rvalue **)args));
1605 }
1606
1607 /* Helper function for determining if we can cast an rvalue from SRC_TYPE
1608 to DST_TYPE, for use by gcc_jit_context_new_cast.
1609
1610 We only permit these kinds of cast:
1611
1612 int <-> float
1613 int <-> bool
1614 P* <-> Q* for pointer types P and Q. */
1615
1616 static bool
is_valid_cast(gcc::jit::recording::type * src_type,gcc_jit_type * dst_type)1617 is_valid_cast (gcc::jit::recording::type *src_type,
1618 gcc_jit_type *dst_type)
1619 {
1620 bool src_is_int = src_type->is_int ();
1621 bool dst_is_int = dst_type->is_int ();
1622 bool src_is_float = src_type->is_float ();
1623 bool dst_is_float = dst_type->is_float ();
1624 bool src_is_bool = src_type->is_bool ();
1625 bool dst_is_bool = dst_type->is_bool ();
1626
1627 if (src_is_int)
1628 if (dst_is_int || dst_is_float || dst_is_bool)
1629 return true;
1630
1631 if (src_is_float)
1632 if (dst_is_int || dst_is_float)
1633 return true;
1634
1635 if (src_is_bool)
1636 if (dst_is_int || dst_is_bool)
1637 return true;
1638
1639 /* Permit casts between pointer types. */
1640 gcc::jit::recording::type *deref_src_type = src_type->is_pointer ();
1641 gcc::jit::recording::type *deref_dst_type = dst_type->is_pointer ();
1642 if (deref_src_type && deref_dst_type)
1643 return true;
1644
1645 return false;
1646 }
1647
1648 /* Public entrypoint. See description in libgccjit.h.
1649
1650 After error-checking, the real work is done by the
1651 gcc::jit::recording::context::new_cast method in jit-recording.c. */
1652
1653 gcc_jit_rvalue *
gcc_jit_context_new_cast(gcc_jit_context * ctxt,gcc_jit_location * loc,gcc_jit_rvalue * rvalue,gcc_jit_type * type)1654 gcc_jit_context_new_cast (gcc_jit_context *ctxt,
1655 gcc_jit_location *loc,
1656 gcc_jit_rvalue *rvalue,
1657 gcc_jit_type *type)
1658 {
1659 RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
1660 JIT_LOG_FUNC (ctxt->get_logger ());
1661 /* LOC can be NULL. */
1662 RETURN_NULL_IF_FAIL (rvalue, ctxt, loc, "NULL rvalue");
1663 RETURN_NULL_IF_FAIL (type, ctxt, loc, "NULL type");
1664 RETURN_NULL_IF_FAIL_PRINTF3 (
1665 is_valid_cast (rvalue->get_type (), type),
1666 ctxt, loc,
1667 "cannot cast %s from type: %s to type: %s",
1668 rvalue->get_debug_string (),
1669 rvalue->get_type ()->get_debug_string (),
1670 type->get_debug_string ());
1671
1672 return static_cast <gcc_jit_rvalue *> (ctxt->new_cast (loc, rvalue, type));
1673 }
1674
1675 /* Public entrypoint. See description in libgccjit.h.
1676
1677 After error-checking, the real work is done by the
1678 gcc::jit::recording::context::new_array_access method in
1679 jit-recording.c. */
1680
1681 extern gcc_jit_lvalue *
gcc_jit_context_new_array_access(gcc_jit_context * ctxt,gcc_jit_location * loc,gcc_jit_rvalue * ptr,gcc_jit_rvalue * index)1682 gcc_jit_context_new_array_access (gcc_jit_context *ctxt,
1683 gcc_jit_location *loc,
1684 gcc_jit_rvalue *ptr,
1685 gcc_jit_rvalue *index)
1686 {
1687 RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
1688 JIT_LOG_FUNC (ctxt->get_logger ());
1689 /* LOC can be NULL. */
1690 RETURN_NULL_IF_FAIL (ptr, ctxt, loc, "NULL ptr");
1691 RETURN_NULL_IF_FAIL (index, ctxt, loc, "NULL index");
1692 RETURN_NULL_IF_FAIL_PRINTF2 (
1693 ptr->get_type ()->dereference (),
1694 ctxt, loc,
1695 "ptr: %s (type: %s) is not a pointer or array",
1696 ptr->get_debug_string (),
1697 ptr->get_type ()->get_debug_string ());
1698 RETURN_NULL_IF_FAIL_PRINTF2 (
1699 index->get_type ()->is_numeric (),
1700 ctxt, loc,
1701 "index: %s (type: %s) is not of numeric type",
1702 index->get_debug_string (),
1703 index->get_type ()->get_debug_string ());
1704
1705 return (gcc_jit_lvalue *)ctxt->new_array_access (loc, ptr, index);
1706 }
1707
1708 /* Public entrypoint. See description in libgccjit.h.
1709
1710 After error-checking, the real work is done by the
1711 gcc::jit::recording::memento::get_context method in
1712 jit-recording.h. */
1713
1714 gcc_jit_context *
gcc_jit_object_get_context(gcc_jit_object * obj)1715 gcc_jit_object_get_context (gcc_jit_object *obj)
1716 {
1717 RETURN_NULL_IF_FAIL (obj, NULL, NULL, "NULL object");
1718
1719 return static_cast <gcc_jit_context *> (obj->get_context ());
1720 }
1721
1722 /* Public entrypoint. See description in libgccjit.h.
1723
1724 After error-checking, the real work is done by the
1725 gcc::jit::recording::memento::get_debug_string method in
1726 jit-recording.c. */
1727
1728 const char *
gcc_jit_object_get_debug_string(gcc_jit_object * obj)1729 gcc_jit_object_get_debug_string (gcc_jit_object *obj)
1730 {
1731 RETURN_NULL_IF_FAIL (obj, NULL, NULL, "NULL object");
1732
1733 return obj->get_debug_string ();
1734 }
1735
1736 /* Public entrypoint. See description in libgccjit.h.
1737
1738 After error-checking, the real work is done by the
1739 gcc::jit::recording::lvalue::access_field method in
1740 jit-recording.c. */
1741
1742 gcc_jit_lvalue *
gcc_jit_lvalue_access_field(gcc_jit_lvalue * struct_,gcc_jit_location * loc,gcc_jit_field * field)1743 gcc_jit_lvalue_access_field (gcc_jit_lvalue *struct_,
1744 gcc_jit_location *loc,
1745 gcc_jit_field *field)
1746 {
1747 RETURN_NULL_IF_FAIL (struct_, NULL, loc, "NULL struct");
1748 gcc::jit::recording::context *ctxt = struct_->m_ctxt;
1749 JIT_LOG_FUNC (ctxt->get_logger ());
1750 /* LOC can be NULL. */
1751 RETURN_NULL_IF_FAIL (field, ctxt, loc, "NULL field");
1752 RETURN_NULL_IF_FAIL_PRINTF1 (field->get_container (), field->m_ctxt, loc,
1753 "field %s has not been placed in a struct",
1754 field->get_debug_string ());
1755 gcc::jit::recording::type *underlying_type =
1756 struct_->get_type ();
1757 RETURN_NULL_IF_FAIL_PRINTF2 (
1758 (field->get_container ()->unqualified ()
1759 == underlying_type->unqualified ()),
1760 struct_->m_ctxt, loc,
1761 "%s is not a field of %s",
1762 field->get_debug_string (),
1763 underlying_type->get_debug_string ());
1764
1765 return (gcc_jit_lvalue *)struct_->access_field (loc, field);
1766 }
1767
1768 /* Public entrypoint. See description in libgccjit.h.
1769
1770 After error-checking, the real work is done by the
1771 gcc::jit::recording::rvalue::access_field method in
1772 jit-recording.c. */
1773
1774 gcc_jit_rvalue *
gcc_jit_rvalue_access_field(gcc_jit_rvalue * struct_,gcc_jit_location * loc,gcc_jit_field * field)1775 gcc_jit_rvalue_access_field (gcc_jit_rvalue *struct_,
1776 gcc_jit_location *loc,
1777 gcc_jit_field *field)
1778 {
1779 RETURN_NULL_IF_FAIL (struct_, NULL, loc, "NULL struct");
1780 gcc::jit::recording::context *ctxt = struct_->m_ctxt;
1781 JIT_LOG_FUNC (ctxt->get_logger ());
1782 /* LOC can be NULL. */
1783 RETURN_NULL_IF_FAIL (field, ctxt, loc, "NULL field");
1784 RETURN_NULL_IF_FAIL_PRINTF1 (field->get_container (), field->m_ctxt, loc,
1785 "field %s has not been placed in a struct",
1786 field->get_debug_string ());
1787 gcc::jit::recording::type *underlying_type =
1788 struct_->get_type ();
1789 RETURN_NULL_IF_FAIL_PRINTF2 (
1790 (field->get_container ()->unqualified ()
1791 == underlying_type->unqualified ()),
1792 struct_->m_ctxt, loc,
1793 "%s is not a field of %s",
1794 field->get_debug_string (),
1795 underlying_type->get_debug_string ());
1796
1797 return (gcc_jit_rvalue *)struct_->access_field (loc, field);
1798 }
1799
1800 /* Public entrypoint. See description in libgccjit.h.
1801
1802 After error-checking, the real work is done by the
1803 gcc::jit::recording::rvalue::deference_field method in
1804 jit-recording.c. */
1805
1806 gcc_jit_lvalue *
gcc_jit_rvalue_dereference_field(gcc_jit_rvalue * ptr,gcc_jit_location * loc,gcc_jit_field * field)1807 gcc_jit_rvalue_dereference_field (gcc_jit_rvalue *ptr,
1808 gcc_jit_location *loc,
1809 gcc_jit_field *field)
1810 {
1811 RETURN_NULL_IF_FAIL (ptr, NULL, loc, "NULL ptr");
1812 JIT_LOG_FUNC (ptr->get_context ()->get_logger ());
1813 /* LOC can be NULL. */
1814 RETURN_NULL_IF_FAIL (field, NULL, loc, "NULL field");
1815 gcc::jit::recording::type *underlying_type =
1816 ptr->get_type ()->is_pointer ();
1817 RETURN_NULL_IF_FAIL_PRINTF1 (field->get_container (), field->m_ctxt, loc,
1818 "field %s has not been placed in a struct",
1819 field->get_debug_string ());
1820 RETURN_NULL_IF_FAIL_PRINTF3 (
1821 underlying_type,
1822 ptr->m_ctxt, loc,
1823 "dereference of non-pointer %s (type: %s) when accessing ->%s",
1824 ptr->get_debug_string (),
1825 ptr->get_type ()->get_debug_string (),
1826 field->get_debug_string ());
1827 RETURN_NULL_IF_FAIL_PRINTF2 (
1828 (field->get_container ()->unqualified ()
1829 == underlying_type->unqualified ()),
1830 ptr->m_ctxt, loc,
1831 "%s is not a field of %s",
1832 field->get_debug_string (),
1833 underlying_type->get_debug_string ());
1834
1835 return (gcc_jit_lvalue *)ptr->dereference_field (loc, field);
1836 }
1837
1838 /* Public entrypoint. See description in libgccjit.h.
1839
1840 After error-checking, the real work is done by the
1841 gcc::jit::recording::rvalue::deference method in
1842 jit-recording.c. */
1843
1844 gcc_jit_lvalue *
gcc_jit_rvalue_dereference(gcc_jit_rvalue * rvalue,gcc_jit_location * loc)1845 gcc_jit_rvalue_dereference (gcc_jit_rvalue *rvalue,
1846 gcc_jit_location *loc)
1847 {
1848 RETURN_NULL_IF_FAIL (rvalue, NULL, loc, "NULL rvalue");
1849 JIT_LOG_FUNC (rvalue->get_context ()->get_logger ());
1850 /* LOC can be NULL. */
1851
1852 gcc::jit::recording::type *underlying_type =
1853 rvalue->get_type ()->is_pointer ();
1854
1855 RETURN_NULL_IF_FAIL_PRINTF2 (
1856 underlying_type,
1857 rvalue->m_ctxt, loc,
1858 "dereference of non-pointer %s (type: %s)",
1859 rvalue->get_debug_string (),
1860 rvalue->get_type ()->get_debug_string ());
1861
1862 RETURN_NULL_IF_FAIL_PRINTF2 (
1863 !underlying_type->is_void (),
1864 rvalue->m_ctxt, loc,
1865 "dereference of void pointer %s (type: %s)",
1866 rvalue->get_debug_string (),
1867 rvalue->get_type ()->get_debug_string ());
1868
1869 return (gcc_jit_lvalue *)rvalue->dereference (loc);
1870 }
1871
1872 /* Public entrypoint. See description in libgccjit.h.
1873
1874 After error-checking, the real work is done by the
1875 gcc::jit::recording::lvalue::get_address method in jit-recording.c. */
1876
1877 gcc_jit_rvalue *
gcc_jit_lvalue_get_address(gcc_jit_lvalue * lvalue,gcc_jit_location * loc)1878 gcc_jit_lvalue_get_address (gcc_jit_lvalue *lvalue,
1879 gcc_jit_location *loc)
1880 {
1881 RETURN_NULL_IF_FAIL (lvalue, NULL, loc, "NULL lvalue");
1882 JIT_LOG_FUNC (lvalue->get_context ()->get_logger ());
1883 /* LOC can be NULL. */
1884
1885 return (gcc_jit_rvalue *)lvalue->get_address (loc);
1886 }
1887
1888 /* Public entrypoint. See description in libgccjit.h.
1889
1890 After error-checking, the real work is done by the
1891 gcc::jit::recording::function::new_local method in jit-recording.c. */
1892
1893 gcc_jit_lvalue *
gcc_jit_function_new_local(gcc_jit_function * func,gcc_jit_location * loc,gcc_jit_type * type,const char * name)1894 gcc_jit_function_new_local (gcc_jit_function *func,
1895 gcc_jit_location *loc,
1896 gcc_jit_type *type,
1897 const char *name)
1898 {
1899 RETURN_NULL_IF_FAIL (func, NULL, loc, "NULL function");
1900 gcc::jit::recording::context *ctxt = func->m_ctxt;
1901 JIT_LOG_FUNC (ctxt->get_logger ());
1902 /* LOC can be NULL. */
1903 RETURN_NULL_IF_FAIL (func->get_kind () != GCC_JIT_FUNCTION_IMPORTED,
1904 ctxt, loc,
1905 "Cannot add locals to an imported function");
1906 RETURN_NULL_IF_FAIL (type, ctxt, loc, "NULL type");
1907 RETURN_NULL_IF_FAIL (name, ctxt, loc, "NULL name");
1908 RETURN_NULL_IF_FAIL_PRINTF2 (
1909 type->has_known_size (),
1910 ctxt, loc,
1911 "unknown size for local \"%s\" (type: %s)",
1912 name,
1913 type->get_debug_string ());
1914
1915 return (gcc_jit_lvalue *)func->new_local (loc, type, name);
1916 }
1917
1918 /* Public entrypoint. See description in libgccjit.h.
1919
1920 After error-checking, the real work is done by the
1921 gcc::jit::recording::block::add_eval method in jit-recording.c. */
1922
1923 void
gcc_jit_block_add_eval(gcc_jit_block * block,gcc_jit_location * loc,gcc_jit_rvalue * rvalue)1924 gcc_jit_block_add_eval (gcc_jit_block *block,
1925 gcc_jit_location *loc,
1926 gcc_jit_rvalue *rvalue)
1927 {
1928 RETURN_IF_NOT_VALID_BLOCK (block, loc);
1929 gcc::jit::recording::context *ctxt = block->get_context ();
1930 JIT_LOG_FUNC (ctxt->get_logger ());
1931 /* LOC can be NULL. */
1932 RETURN_IF_FAIL (rvalue, ctxt, loc, "NULL rvalue");
1933
1934 gcc::jit::recording::statement *stmt = block->add_eval (loc, rvalue);
1935
1936 /* "stmt" should be good enough to be usable in error-messages,
1937 but might still not be compilable; perform some more
1938 error-checking here. We do this here so that the error messages
1939 can contain a stringified version of "stmt", whilst appearing
1940 as close as possible to the point of failure. */
1941 rvalue->verify_valid_within_stmt (__func__, stmt);
1942 }
1943
1944 /* Public entrypoint. See description in libgccjit.h.
1945
1946 After error-checking, the real work is done by the
1947 gcc::jit::recording::block::add_assignment method in
1948 jit-recording.c. */
1949
1950 void
gcc_jit_block_add_assignment(gcc_jit_block * block,gcc_jit_location * loc,gcc_jit_lvalue * lvalue,gcc_jit_rvalue * rvalue)1951 gcc_jit_block_add_assignment (gcc_jit_block *block,
1952 gcc_jit_location *loc,
1953 gcc_jit_lvalue *lvalue,
1954 gcc_jit_rvalue *rvalue)
1955 {
1956 RETURN_IF_NOT_VALID_BLOCK (block, loc);
1957 gcc::jit::recording::context *ctxt = block->get_context ();
1958 JIT_LOG_FUNC (ctxt->get_logger ());
1959 /* LOC can be NULL. */
1960 RETURN_IF_FAIL (lvalue, ctxt, loc, "NULL lvalue");
1961 RETURN_IF_FAIL (rvalue, ctxt, loc, "NULL rvalue");
1962 RETURN_IF_FAIL_PRINTF4 (
1963 compatible_types (lvalue->get_type (),
1964 rvalue->get_type ()),
1965 ctxt, loc,
1966 "mismatching types:"
1967 " assignment to %s (type: %s) from %s (type: %s)",
1968 lvalue->get_debug_string (),
1969 lvalue->get_type ()->get_debug_string (),
1970 rvalue->get_debug_string (),
1971 rvalue->get_type ()->get_debug_string ());
1972
1973 gcc::jit::recording::statement *stmt = block->add_assignment (loc, lvalue, rvalue);
1974
1975 /* "stmt" should be good enough to be usable in error-messages,
1976 but might still not be compilable; perform some more
1977 error-checking here. We do this here so that the error messages
1978 can contain a stringified version of "stmt", whilst appearing
1979 as close as possible to the point of failure. */
1980 lvalue->verify_valid_within_stmt (__func__, stmt);
1981 rvalue->verify_valid_within_stmt (__func__, stmt);
1982 }
1983
1984 /* Public entrypoint. See description in libgccjit.h.
1985
1986 After error-checking, the real work is done by the
1987 gcc::jit::recording::block::add_assignment_op method in
1988 jit-recording.c. */
1989
1990 void
gcc_jit_block_add_assignment_op(gcc_jit_block * block,gcc_jit_location * loc,gcc_jit_lvalue * lvalue,enum gcc_jit_binary_op op,gcc_jit_rvalue * rvalue)1991 gcc_jit_block_add_assignment_op (gcc_jit_block *block,
1992 gcc_jit_location *loc,
1993 gcc_jit_lvalue *lvalue,
1994 enum gcc_jit_binary_op op,
1995 gcc_jit_rvalue *rvalue)
1996 {
1997 RETURN_IF_NOT_VALID_BLOCK (block, loc);
1998 gcc::jit::recording::context *ctxt = block->get_context ();
1999 JIT_LOG_FUNC (ctxt->get_logger ());
2000 /* LOC can be NULL. */
2001 RETURN_IF_FAIL (lvalue, ctxt, loc, "NULL lvalue");
2002 RETURN_IF_FAIL_PRINTF1 (
2003 valid_binary_op_p (op),
2004 ctxt, loc,
2005 "unrecognized value for enum gcc_jit_binary_op: %i",
2006 op);
2007 RETURN_IF_FAIL (rvalue, ctxt, loc, "NULL rvalue");
2008 RETURN_IF_FAIL_PRINTF4 (
2009 compatible_types (lvalue->get_type (),
2010 rvalue->get_type ()),
2011 ctxt, loc,
2012 "mismatching types:"
2013 " assignment to %s (type: %s) involving %s (type: %s)",
2014 lvalue->get_debug_string (),
2015 lvalue->get_type ()->get_debug_string (),
2016 rvalue->get_debug_string (),
2017 rvalue->get_type ()->get_debug_string ());
2018
2019 gcc::jit::recording::statement *stmt = block->add_assignment_op (loc, lvalue, op, rvalue);
2020
2021 /* "stmt" should be good enough to be usable in error-messages,
2022 but might still not be compilable; perform some more
2023 error-checking here. We do this here so that the error messages
2024 can contain a stringified version of "stmt", whilst appearing
2025 as close as possible to the point of failure. */
2026 lvalue->verify_valid_within_stmt (__func__, stmt);
2027 rvalue->verify_valid_within_stmt (__func__, stmt);
2028 }
2029
2030 /* Internal helper function for determining if rvalue BOOLVAL is of
2031 boolean type. For use by gcc_jit_block_end_with_conditional. */
2032
2033 static bool
is_bool(gcc_jit_rvalue * boolval)2034 is_bool (gcc_jit_rvalue *boolval)
2035 {
2036 gcc::jit::recording::type *actual_type = boolval->get_type ();
2037 gcc::jit::recording::type *bool_type =
2038 boolval->m_ctxt->get_type (GCC_JIT_TYPE_BOOL);
2039 return actual_type == bool_type;
2040 }
2041
2042 /* Public entrypoint. See description in libgccjit.h.
2043
2044 After error-checking, the real work is done by the
2045 gcc::jit::recording::block::end_with_conditional method in
2046 jit-recording.c. */
2047
2048 void
gcc_jit_block_end_with_conditional(gcc_jit_block * block,gcc_jit_location * loc,gcc_jit_rvalue * boolval,gcc_jit_block * on_true,gcc_jit_block * on_false)2049 gcc_jit_block_end_with_conditional (gcc_jit_block *block,
2050 gcc_jit_location *loc,
2051 gcc_jit_rvalue *boolval,
2052 gcc_jit_block *on_true,
2053 gcc_jit_block *on_false)
2054 {
2055 RETURN_IF_NOT_VALID_BLOCK (block, loc);
2056 gcc::jit::recording::context *ctxt = block->get_context ();
2057 JIT_LOG_FUNC (ctxt->get_logger ());
2058 /* LOC can be NULL. */
2059 RETURN_IF_FAIL (boolval, ctxt, loc, "NULL boolval");
2060 RETURN_IF_FAIL_PRINTF2 (
2061 is_bool (boolval), ctxt, loc,
2062 "%s (type: %s) is not of boolean type ",
2063 boolval->get_debug_string (),
2064 boolval->get_type ()->get_debug_string ());
2065 RETURN_IF_FAIL (on_true, ctxt, loc, "NULL on_true");
2066 RETURN_IF_FAIL (on_true, ctxt, loc, "NULL on_false");
2067 RETURN_IF_FAIL_PRINTF4 (
2068 block->get_function () == on_true->get_function (),
2069 ctxt, loc,
2070 "\"on_true\" block is not in same function:"
2071 " source block %s is in function %s"
2072 " whereas target block %s is in function %s",
2073 block->get_debug_string (),
2074 block->get_function ()->get_debug_string (),
2075 on_true->get_debug_string (),
2076 on_true->get_function ()->get_debug_string ());
2077 RETURN_IF_FAIL_PRINTF4 (
2078 block->get_function () == on_false->get_function (),
2079 ctxt, loc,
2080 "\"on_false\" block is not in same function:"
2081 " source block %s is in function %s"
2082 " whereas target block %s is in function %s",
2083 block->get_debug_string (),
2084 block->get_function ()->get_debug_string (),
2085 on_false->get_debug_string (),
2086 on_false->get_function ()->get_debug_string ());
2087
2088 gcc::jit::recording::statement *stmt = block->end_with_conditional (loc, boolval, on_true, on_false);
2089
2090 /* "stmt" should be good enough to be usable in error-messages,
2091 but might still not be compilable; perform some more
2092 error-checking here. We do this here so that the error messages
2093 can contain a stringified version of "stmt", whilst appearing
2094 as close as possible to the point of failure. */
2095 boolval->verify_valid_within_stmt (__func__, stmt);
2096 }
2097
2098 /* Public entrypoint. See description in libgccjit.h.
2099
2100 After error-checking, the real work is done by the
2101 gcc::jit::recording::block::add_comment method in
2102 jit-recording.c. */
2103
2104 void
gcc_jit_block_add_comment(gcc_jit_block * block,gcc_jit_location * loc,const char * text)2105 gcc_jit_block_add_comment (gcc_jit_block *block,
2106 gcc_jit_location *loc,
2107 const char *text)
2108 {
2109 RETURN_IF_NOT_VALID_BLOCK (block, loc);
2110 gcc::jit::recording::context *ctxt = block->get_context ();
2111 JIT_LOG_FUNC (ctxt->get_logger ());
2112 /* LOC can be NULL. */
2113 RETURN_IF_FAIL (text, ctxt, loc, "NULL text");
2114
2115 block->add_comment (loc, text);
2116 }
2117
2118 /* Public entrypoint. See description in libgccjit.h.
2119
2120 After error-checking, the real work is done by the
2121 gcc::jit::recording::block::end_with_jump method in
2122 jit-recording.c. */
2123
2124 void
gcc_jit_block_end_with_jump(gcc_jit_block * block,gcc_jit_location * loc,gcc_jit_block * target)2125 gcc_jit_block_end_with_jump (gcc_jit_block *block,
2126 gcc_jit_location *loc,
2127 gcc_jit_block *target)
2128 {
2129 RETURN_IF_NOT_VALID_BLOCK (block, loc);
2130 gcc::jit::recording::context *ctxt = block->get_context ();
2131 JIT_LOG_FUNC (ctxt->get_logger ());
2132 /* LOC can be NULL. */
2133 RETURN_IF_FAIL (target, ctxt, loc, "NULL target");
2134 RETURN_IF_FAIL_PRINTF4 (
2135 block->get_function () == target->get_function (),
2136 ctxt, loc,
2137 "target block is not in same function:"
2138 " source block %s is in function %s"
2139 " whereas target block %s is in function %s",
2140 block->get_debug_string (),
2141 block->get_function ()->get_debug_string (),
2142 target->get_debug_string (),
2143 target->get_function ()->get_debug_string ());
2144
2145 block->end_with_jump (loc, target);
2146 }
2147
2148 /* Public entrypoint. See description in libgccjit.h.
2149
2150 After error-checking, the real work is done by the
2151 gcc::jit::recording::block::end_with_return method in
2152 jit-recording.c. */
2153
2154 void
gcc_jit_block_end_with_return(gcc_jit_block * block,gcc_jit_location * loc,gcc_jit_rvalue * rvalue)2155 gcc_jit_block_end_with_return (gcc_jit_block *block,
2156 gcc_jit_location *loc,
2157 gcc_jit_rvalue *rvalue)
2158 {
2159 RETURN_IF_NOT_VALID_BLOCK (block, loc);
2160 gcc::jit::recording::context *ctxt = block->get_context ();
2161 JIT_LOG_FUNC (ctxt->get_logger ());
2162 /* LOC can be NULL. */
2163 gcc::jit::recording::function *func = block->get_function ();
2164 RETURN_IF_FAIL (rvalue, ctxt, loc, "NULL rvalue");
2165 RETURN_IF_FAIL_PRINTF4 (
2166 compatible_types (
2167 func->get_return_type (),
2168 rvalue->get_type ()),
2169 ctxt, loc,
2170 "mismatching types:"
2171 " return of %s (type: %s) in function %s (return type: %s)",
2172 rvalue->get_debug_string (),
2173 rvalue->get_type ()->get_debug_string (),
2174 func->get_debug_string (),
2175 func->get_return_type ()->get_debug_string ());
2176
2177 gcc::jit::recording::statement *stmt = block->end_with_return (loc, rvalue);
2178
2179 /* "stmt" should be good enough to be usable in error-messages,
2180 but might still not be compilable; perform some more
2181 error-checking here. We do this here so that the error messages
2182 can contain a stringified version of "stmt", whilst appearing
2183 as close as possible to the point of failure. */
2184 rvalue->verify_valid_within_stmt (__func__, stmt);
2185 }
2186
2187 /* Public entrypoint. See description in libgccjit.h.
2188
2189 After error-checking, the real work is done by the
2190 gcc::jit::recording::block::end_with_return method in
2191 jit-recording.c. */
2192
2193 void
gcc_jit_block_end_with_void_return(gcc_jit_block * block,gcc_jit_location * loc)2194 gcc_jit_block_end_with_void_return (gcc_jit_block *block,
2195 gcc_jit_location *loc)
2196 {
2197 RETURN_IF_NOT_VALID_BLOCK (block, loc);
2198 gcc::jit::recording::context *ctxt = block->get_context ();
2199 JIT_LOG_FUNC (ctxt->get_logger ());
2200 /* LOC can be NULL. */
2201 gcc::jit::recording::function *func = block->get_function ();
2202 RETURN_IF_FAIL_PRINTF2 (
2203 func->get_return_type () == ctxt->get_type (GCC_JIT_TYPE_VOID),
2204 ctxt, loc,
2205 "mismatching types:"
2206 " void return in function %s (return type: %s)",
2207 func->get_debug_string (),
2208 func->get_return_type ()->get_debug_string ());
2209
2210 block->end_with_return (loc, NULL);
2211 }
2212
2213 /* Public entrypoint. See description in libgccjit.h.
2214
2215 After error-checking, the real work is done by the
2216 gcc::jit::recording::context::new_case method in
2217 jit-recording.c. */
2218
2219 gcc_jit_case *
gcc_jit_context_new_case(gcc_jit_context * ctxt,gcc_jit_rvalue * min_value,gcc_jit_rvalue * max_value,gcc_jit_block * block)2220 gcc_jit_context_new_case (gcc_jit_context *ctxt,
2221 gcc_jit_rvalue *min_value,
2222 gcc_jit_rvalue *max_value,
2223 gcc_jit_block *block)
2224 {
2225 RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
2226 JIT_LOG_FUNC (ctxt->get_logger ());
2227 RETURN_NULL_IF_FAIL (min_value, ctxt, NULL, "NULL min_value");
2228 RETURN_NULL_IF_FAIL (max_value, ctxt, NULL, "NULL max_value");
2229 RETURN_NULL_IF_FAIL (block, ctxt, NULL, "NULL block");
2230
2231 RETURN_NULL_IF_FAIL_PRINTF1 (min_value->is_constant (), ctxt, NULL,
2232 "min_value is not a constant: %s",
2233 min_value->get_debug_string ());
2234 RETURN_NULL_IF_FAIL_PRINTF1 (max_value->is_constant (), ctxt, NULL,
2235 "max_value is not a constant: %s",
2236 max_value->get_debug_string ());
2237 RETURN_NULL_IF_FAIL_PRINTF2 (
2238 min_value->get_type ()->is_int (),
2239 ctxt, NULL,
2240 "min_value: %s (type: %s) is not of integer type",
2241 min_value->get_debug_string (),
2242 min_value->get_type ()->get_debug_string ());
2243 RETURN_NULL_IF_FAIL_PRINTF2 (
2244 max_value->get_type ()->is_int (),
2245 ctxt, NULL,
2246 "max_value: %s (type: %s) is not of integer type",
2247 max_value->get_debug_string (),
2248 max_value->get_type ()->get_debug_string ());
2249
2250 wide_int wi_min, wi_max;
2251 if (!min_value->get_wide_int (&wi_min))
2252 gcc_unreachable ();
2253 if (!max_value->get_wide_int (&wi_max))
2254 gcc_unreachable ();
2255 RETURN_NULL_IF_FAIL_PRINTF2 (
2256 wi::les_p (wi_min, wi_max),
2257 ctxt, NULL,
2258 "min_value: %s > max_value: %s",
2259 min_value->get_debug_string (),
2260 max_value->get_debug_string ());
2261 return (gcc_jit_case *)ctxt->new_case (min_value,
2262 max_value,
2263 block);
2264 }
2265
2266 /* Public entrypoint. See description in libgccjit.h.
2267
2268 After error-checking, this calls the trivial
2269 gcc::jit::recording::memento::as_object method (a case is a
2270 memento), in jit-recording.h. */
2271
2272 gcc_jit_object *
gcc_jit_case_as_object(gcc_jit_case * case_)2273 gcc_jit_case_as_object (gcc_jit_case *case_)
2274 {
2275 RETURN_NULL_IF_FAIL (case_, NULL, NULL, "NULL case");
2276
2277 return static_cast <gcc_jit_object *> (case_->as_object ());
2278 }
2279
2280 /* Helper function for gcc_jit_block_end_with_switch and
2281 valid_case_for_switch. */
2282
2283 static bool
valid_dest_for_switch(gcc::jit::recording::context * ctxt,gcc_jit_location * loc,const char * api_funcname,gcc::jit::recording::block * switch_block,gcc::jit::recording::block * dest_block,const char * dest_block_desc)2284 valid_dest_for_switch (gcc::jit::recording::context *ctxt,
2285 gcc_jit_location *loc,
2286 const char *api_funcname,
2287 gcc::jit::recording::block *switch_block,
2288 gcc::jit::recording::block *dest_block,
2289 const char *dest_block_desc)
2290 {
2291 if (!dest_block)
2292 {
2293 jit_error (ctxt, loc, "%s: NULL %s", api_funcname, dest_block_desc);
2294 return false;
2295 }
2296 gcc::jit::recording::function *switch_fn = switch_block->get_function ();
2297 gcc::jit::recording::function *dest_fn = dest_block->get_function ();
2298 if (switch_fn != dest_fn)
2299 {
2300 jit_error (ctxt, loc,
2301 "%s: %s is not in same function:"
2302 " switch block %s is in function %s"
2303 " whereas %s %s is in function %s",
2304 api_funcname,
2305 dest_block_desc,
2306 switch_block->get_debug_string (),
2307 switch_fn->get_debug_string (),
2308 dest_block_desc,
2309 dest_block->get_debug_string (),
2310 dest_fn->get_debug_string ());
2311 return false;
2312 }
2313 return true;
2314 }
2315
2316 /* Helper function for gcc_jit_block_end_with_switch. */
2317
2318 static bool
valid_case_for_switch(gcc::jit::recording::context * ctxt,gcc_jit_location * loc,const char * api_funcname,gcc_jit_block * switch_block,gcc_jit_rvalue * expr,gcc_jit_case * case_,const char * case_desc,int case_idx)2319 valid_case_for_switch (gcc::jit::recording::context *ctxt,
2320 gcc_jit_location *loc,
2321 const char *api_funcname,
2322 gcc_jit_block *switch_block,
2323 gcc_jit_rvalue *expr,
2324 gcc_jit_case *case_,
2325 const char *case_desc,
2326 int case_idx)
2327 {
2328 if (!case_)
2329 {
2330 jit_error (ctxt, loc,
2331 "%s:"
2332 " NULL case %i",
2333 api_funcname,
2334 case_idx);
2335 return false;
2336 }
2337 if (!valid_dest_for_switch (ctxt, loc,
2338 api_funcname,
2339 switch_block,
2340 case_->get_dest_block (),
2341 case_desc))
2342 return false;
2343 gcc::jit::recording::type *expr_type = expr->get_type ();
2344 if (expr_type != case_->get_min_value ()->get_type ())
2345 {
2346 jit_error (ctxt, loc,
2347 "%s:"
2348 " mismatching types between case and expression:"
2349 " cases[%i]->min_value: %s (type: %s)"
2350 " expr: %s (type: %s)",
2351 api_funcname,
2352 case_idx,
2353 case_->get_min_value ()->get_debug_string (),
2354 case_->get_min_value ()->get_type ()->get_debug_string (),
2355 expr->get_debug_string (),
2356 expr_type->get_debug_string ());
2357 return false;
2358 }
2359 if (expr_type != case_->get_max_value ()->get_type ())
2360 {
2361 jit_error (ctxt, loc,
2362 "%s:"
2363 " mismatching types between case and expression:"
2364 " cases[%i]->max_value: %s (type: %s)"
2365 " expr: %s (type: %s)",
2366 api_funcname,
2367 case_idx,
2368 case_->get_max_value ()->get_debug_string (),
2369 case_->get_max_value ()->get_type ()->get_debug_string (),
2370 expr->get_debug_string (),
2371 expr_type->get_debug_string ());
2372 return false;
2373 }
2374 return true;
2375 }
2376
2377 /* A class for holding the data we need to perform error-checking
2378 on a libgccjit API call. */
2379
2380 class api_call_validator
2381 {
2382 public:
api_call_validator(gcc::jit::recording::context * ctxt,gcc_jit_location * loc,const char * funcname)2383 api_call_validator (gcc::jit::recording::context *ctxt,
2384 gcc_jit_location *loc,
2385 const char *funcname)
2386 : m_ctxt (ctxt),
2387 m_loc (loc),
2388 m_funcname (funcname)
2389 {}
2390
2391 protected:
2392 gcc::jit::recording::context *m_ctxt;
2393 gcc_jit_location *m_loc;
2394 const char *m_funcname;
2395 };
2396
2397 /* A class for verifying that the ranges of cases within
2398 gcc_jit_block_end_with_switch don't overlap. */
2399
2400 class case_range_validator : public api_call_validator
2401 {
2402 public:
2403 case_range_validator (gcc::jit::recording::context *ctxt,
2404 gcc_jit_location *loc,
2405 const char *funcname);
2406
2407 bool
2408 validate (gcc_jit_case *case_, int idx);
2409
2410 private:
2411 static int
2412 case_compare (gcc::jit::recording::rvalue *k1,
2413 gcc::jit::recording::rvalue *k2);
2414
2415 static wide_int
2416 get_wide_int (gcc::jit::recording::rvalue *k);
2417
2418 private:
2419 typed_splay_tree <gcc::jit::recording::rvalue *, gcc_jit_case *> m_cases;
2420 };
2421
2422 /* case_range_validator's ctor. */
2423
case_range_validator(gcc::jit::recording::context * ctxt,gcc_jit_location * loc,const char * funcname)2424 case_range_validator::case_range_validator (gcc::jit::recording::context *ctxt,
2425 gcc_jit_location *loc,
2426 const char *funcname)
2427 : api_call_validator (ctxt, loc, funcname),
2428 m_cases (case_compare, NULL, NULL)
2429 {
2430 }
2431
2432 /* Ensure that the range of CASE_ does not overlap with any of the
2433 ranges of cases we've already seen.
2434 Return true if everything is OK.
2435 Return false and emit an error if there is an overlap.
2436 Compare with c-family/c-common.c:c_add_case_label. */
2437
2438 bool
validate(gcc_jit_case * case_,int case_idx)2439 case_range_validator::validate (gcc_jit_case *case_,
2440 int case_idx)
2441 {
2442 /* Look up the LOW_VALUE in the table of case labels we already
2443 have. */
2444 gcc_jit_case *other = m_cases.lookup (case_->get_min_value ());
2445
2446 /* If there was not an exact match, check for overlapping ranges. */
2447 if (!other)
2448 {
2449 gcc_jit_case *pred;
2450 gcc_jit_case *succ;
2451
2452 /* Even though there wasn't an exact match, there might be an
2453 overlap between this case range and another case range.
2454 Since we've (inductively) not allowed any overlapping case
2455 ranges, we simply need to find the greatest low case label
2456 that is smaller that CASE_MIN_VALUE, and the smallest low case
2457 label that is greater than CASE_MAX_VALUE. If there is an overlap
2458 it will occur in one of these two ranges. */
2459 pred = m_cases.predecessor (case_->get_min_value ());
2460 succ = m_cases.successor (case_->get_max_value ());
2461
2462 /* Check to see if the PRED overlaps. It is smaller than
2463 the LOW_VALUE, so we only need to check its max value. */
2464 if (pred)
2465 {
2466 wide_int wi_case_min = get_wide_int (case_->get_min_value ());
2467 wide_int wi_pred_max = get_wide_int (pred->get_max_value ());
2468 if (wi::ges_p (wi_pred_max, wi_case_min))
2469 other = pred;
2470 }
2471
2472 if (!other && succ)
2473 {
2474 /* Check to see if the SUCC overlaps. The low end of that
2475 range is bigger than the low end of the current range. */
2476 wide_int wi_case_max = get_wide_int (case_->get_max_value ());
2477 wide_int wi_succ_min = get_wide_int (succ->get_min_value ());
2478 if (wi::les_p (wi_succ_min, wi_case_max))
2479 other = succ;
2480 }
2481 }
2482
2483 /* If there was an overlap, issue an error. */
2484 if (other)
2485 {
2486 jit_error (m_ctxt, m_loc,
2487 "%s: duplicate (or overlapping) cases values:"
2488 " case %i: %s overlaps %s",
2489 m_funcname,
2490 case_idx,
2491 case_->get_debug_string (),
2492 other->get_debug_string ());
2493 return false;
2494 }
2495
2496 /* Register this case label in the splay tree. */
2497 m_cases.insert (case_->get_min_value (),
2498 case_);
2499 return true;
2500 }
2501
2502 /* Compare with c-family/c-common.c:case_compare, which acts on tree
2503 nodes, rather than rvalue *.
2504
2505 Comparator for case label values. K1 and K2 must be constant integer
2506 values (anything else should have been rejected by
2507 gcc_jit_context_new_case.
2508
2509 Returns -1 if K1 is ordered before K2, -1 if K1 is ordered after
2510 K2, and 0 if K1 and K2 are equal. */
2511
2512 int
case_compare(gcc::jit::recording::rvalue * k1,gcc::jit::recording::rvalue * k2)2513 case_range_validator::case_compare (gcc::jit::recording::rvalue * k1,
2514 gcc::jit::recording::rvalue * k2)
2515 {
2516 wide_int wi1 = get_wide_int (k1);
2517 wide_int wi2 = get_wide_int (k2);
2518 return wi::cmps(wi1, wi2);
2519 }
2520
2521 /* Given a const int rvalue K, get the underlying value as a wide_int. */
2522
2523 wide_int
get_wide_int(gcc::jit::recording::rvalue * k)2524 case_range_validator::get_wide_int (gcc::jit::recording::rvalue *k)
2525 {
2526 wide_int wi;
2527 bool got_wi = k->get_wide_int (&wi);
2528 gcc_assert (got_wi);
2529 return wi;
2530 }
2531
2532 /* Public entrypoint. See description in libgccjit.h.
2533
2534 After error-checking, the real work is done by the
2535 gcc::jit::recording::block::end_with_switch method in
2536 jit-recording.c. */
2537
2538 void
gcc_jit_block_end_with_switch(gcc_jit_block * block,gcc_jit_location * loc,gcc_jit_rvalue * expr,gcc_jit_block * default_block,int num_cases,gcc_jit_case ** cases)2539 gcc_jit_block_end_with_switch (gcc_jit_block *block,
2540 gcc_jit_location *loc,
2541 gcc_jit_rvalue *expr,
2542 gcc_jit_block *default_block,
2543 int num_cases,
2544 gcc_jit_case **cases)
2545 {
2546 RETURN_IF_NOT_VALID_BLOCK (block, loc);
2547 gcc::jit::recording::context *ctxt = block->get_context ();
2548 JIT_LOG_FUNC (ctxt->get_logger ());
2549 /* LOC can be NULL. */
2550 RETURN_IF_FAIL (expr, ctxt, loc,
2551 "NULL expr");
2552 gcc::jit::recording::type *expr_type = expr->get_type ();
2553 RETURN_IF_FAIL_PRINTF2 (
2554 expr_type->is_int (),
2555 ctxt, loc,
2556 "expr: %s (type: %s) is not of integer type",
2557 expr->get_debug_string (),
2558 expr_type->get_debug_string ());
2559 if (!valid_dest_for_switch (ctxt, loc,
2560 __func__,
2561 block,
2562 default_block,
2563 "default_block"))
2564 return;
2565 RETURN_IF_FAIL (num_cases >= 0, ctxt, loc, "num_cases < 0");
2566 case_range_validator crv (ctxt, loc, __func__);
2567 for (int i = 0; i < num_cases; i++)
2568 {
2569 char case_desc[32];
2570 snprintf (case_desc, sizeof (case_desc),
2571 "cases[%i]", i);
2572 if (!valid_case_for_switch (ctxt, loc,
2573 __func__,
2574 block,
2575 expr,
2576 cases[i],
2577 case_desc,
2578 i))
2579 return;
2580 if (!crv.validate (cases[i], i))
2581 return;
2582 }
2583
2584 block->end_with_switch (loc, expr, default_block,
2585 num_cases,
2586 (gcc::jit::recording::case_ **)cases);
2587 }
2588
2589 /**********************************************************************
2590 Option-management
2591 **********************************************************************/
2592
2593 /* Public entrypoint. See description in libgccjit.h.
2594
2595 After error-checking, the real work is done by the
2596 gcc::jit::recording::context::set_str_option method in
2597 jit-recording.c. */
2598
2599 void
gcc_jit_context_set_str_option(gcc_jit_context * ctxt,enum gcc_jit_str_option opt,const char * value)2600 gcc_jit_context_set_str_option (gcc_jit_context *ctxt,
2601 enum gcc_jit_str_option opt,
2602 const char *value)
2603 {
2604 RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
2605 JIT_LOG_FUNC (ctxt->get_logger ());
2606 /* opt is checked by the inner function.
2607 value can be NULL. */
2608
2609 ctxt->set_str_option (opt, value);
2610 }
2611
2612 /* Public entrypoint. See description in libgccjit.h.
2613
2614 After error-checking, the real work is done by the
2615 gcc::jit::recording::context::set_int_option method in
2616 jit-recording.c. */
2617
2618 void
gcc_jit_context_set_int_option(gcc_jit_context * ctxt,enum gcc_jit_int_option opt,int value)2619 gcc_jit_context_set_int_option (gcc_jit_context *ctxt,
2620 enum gcc_jit_int_option opt,
2621 int value)
2622 {
2623 RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
2624 JIT_LOG_FUNC (ctxt->get_logger ());
2625 /* opt is checked by the inner function. */
2626
2627 ctxt->set_int_option (opt, value);
2628 }
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::set_bool_option method in
2634 jit-recording.c. */
2635
2636 void
gcc_jit_context_set_bool_option(gcc_jit_context * ctxt,enum gcc_jit_bool_option opt,int value)2637 gcc_jit_context_set_bool_option (gcc_jit_context *ctxt,
2638 enum gcc_jit_bool_option opt,
2639 int value)
2640 {
2641 RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
2642 JIT_LOG_FUNC (ctxt->get_logger ());
2643 /* opt is checked by the inner function. */
2644
2645 ctxt->set_bool_option (opt, value);
2646 }
2647
2648 /* Public entrypoint. See description in libgccjit.h.
2649
2650 After error-checking, the real work is done by the
2651 gcc::jit::recording::context::set_inner_bool_option method in
2652 jit-recording.c. */
2653
2654 void
gcc_jit_context_set_bool_allow_unreachable_blocks(gcc_jit_context * ctxt,int bool_value)2655 gcc_jit_context_set_bool_allow_unreachable_blocks (gcc_jit_context *ctxt,
2656 int bool_value)
2657 {
2658 RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
2659 JIT_LOG_FUNC (ctxt->get_logger ());
2660 ctxt->set_inner_bool_option (
2661 gcc::jit::INNER_BOOL_OPTION_ALLOW_UNREACHABLE_BLOCKS,
2662 bool_value);
2663 }
2664
2665 /* Public entrypoint. See description in libgccjit.h.
2666
2667 After error-checking, the real work is done by the
2668 gcc::jit::recording::context::set_inner_bool_option method in
2669 jit-recording.c. */
2670
2671 extern void
gcc_jit_context_set_bool_use_external_driver(gcc_jit_context * ctxt,int bool_value)2672 gcc_jit_context_set_bool_use_external_driver (gcc_jit_context *ctxt,
2673 int bool_value)
2674 {
2675 RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
2676 JIT_LOG_FUNC (ctxt->get_logger ());
2677 ctxt->set_inner_bool_option (
2678 gcc::jit::INNER_BOOL_OPTION_USE_EXTERNAL_DRIVER,
2679 bool_value);
2680 }
2681
2682 /* Public entrypoint. See description in libgccjit.h.
2683
2684 After error-checking, the real work is done by the
2685 gcc::jit::recording::context::add_command_line_option method in
2686 jit-recording.c. */
2687
2688 void
gcc_jit_context_add_command_line_option(gcc_jit_context * ctxt,const char * optname)2689 gcc_jit_context_add_command_line_option (gcc_jit_context *ctxt,
2690 const char *optname)
2691 {
2692 RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
2693 JIT_LOG_FUNC (ctxt->get_logger ());
2694 RETURN_IF_FAIL (optname, ctxt, NULL, "NULL optname");
2695 if (ctxt->get_logger ())
2696 ctxt->get_logger ()->log ("optname: %s", optname);
2697
2698 ctxt->add_command_line_option (optname);
2699 }
2700
2701 /* Public entrypoint. See description in libgccjit.h.
2702
2703 The real work is done by the
2704 gcc::jit::recording::context::add_driver_option method in
2705 jit-recording.c. */
2706
2707 void
gcc_jit_context_add_driver_option(gcc_jit_context * ctxt,const char * optname)2708 gcc_jit_context_add_driver_option (gcc_jit_context *ctxt,
2709 const char *optname)
2710 {
2711 RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
2712 JIT_LOG_FUNC (ctxt->get_logger ());
2713 RETURN_IF_FAIL (optname, ctxt, NULL, "NULL optname");
2714 if (ctxt->get_logger ())
2715 ctxt->get_logger ()->log ("optname: %s", optname);
2716
2717 ctxt->add_driver_option (optname);
2718 }
2719
2720 /* Public entrypoint. See description in libgccjit.h.
2721
2722 After error-checking, the real work is done by the
2723 gcc::jit::recording::context::enable_dump method in
2724 jit-recording.c. */
2725
2726 void
gcc_jit_context_enable_dump(gcc_jit_context * ctxt,const char * dumpname,char ** out_ptr)2727 gcc_jit_context_enable_dump (gcc_jit_context *ctxt,
2728 const char *dumpname,
2729 char **out_ptr)
2730 {
2731 RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
2732 JIT_LOG_FUNC (ctxt->get_logger ());
2733 RETURN_IF_FAIL (dumpname, ctxt, NULL, "NULL dumpname");
2734 RETURN_IF_FAIL (out_ptr, ctxt, NULL, "NULL out_ptr");
2735
2736 ctxt->enable_dump (dumpname, out_ptr);
2737 }
2738
2739 /* Public entrypoint. See description in libgccjit.h.
2740
2741 After error-checking, the real work is done by the
2742 gcc::jit::recording::context::compile method in
2743 jit-recording.c. */
2744
2745 gcc_jit_result *
gcc_jit_context_compile(gcc_jit_context * ctxt)2746 gcc_jit_context_compile (gcc_jit_context *ctxt)
2747 {
2748 RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
2749
2750 JIT_LOG_FUNC (ctxt->get_logger ());
2751
2752 ctxt->log ("in-memory compile of ctxt: %p", (void *)ctxt);
2753
2754 gcc_jit_result *result = (gcc_jit_result *)ctxt->compile ();
2755
2756 ctxt->log ("%s: returning (gcc_jit_result *)%p",
2757 __func__, (void *)result);
2758
2759 return result;
2760 }
2761
2762 /* Public entrypoint. See description in libgccjit.h.
2763
2764 After error-checking, the real work is done by the
2765 gcc::jit::recording::context::compile_to_file method in
2766 jit-recording.c. */
2767
2768 void
gcc_jit_context_compile_to_file(gcc_jit_context * ctxt,enum gcc_jit_output_kind output_kind,const char * output_path)2769 gcc_jit_context_compile_to_file (gcc_jit_context *ctxt,
2770 enum gcc_jit_output_kind output_kind,
2771 const char *output_path)
2772 {
2773 RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
2774 JIT_LOG_FUNC (ctxt->get_logger ());
2775 RETURN_IF_FAIL_PRINTF1 (
2776 ((output_kind >= GCC_JIT_OUTPUT_KIND_ASSEMBLER)
2777 && (output_kind <= GCC_JIT_OUTPUT_KIND_EXECUTABLE)),
2778 ctxt, NULL,
2779 "unrecognized output_kind: %i",
2780 output_kind);
2781 RETURN_IF_FAIL (output_path, ctxt, NULL, "NULL output_path");
2782
2783 ctxt->log ("compile_to_file of ctxt: %p", (void *)ctxt);
2784 ctxt->log ("output_kind: %i", output_kind);
2785 ctxt->log ("output_path: %s", output_path);
2786
2787 ctxt->compile_to_file (output_kind, output_path);
2788 }
2789
2790
2791 /* Public entrypoint. See description in libgccjit.h.
2792
2793 After error-checking, the real work is done by the
2794 gcc::jit::recording::context::dump_to_file method in
2795 jit-recording.c. */
2796
2797 void
gcc_jit_context_dump_to_file(gcc_jit_context * ctxt,const char * path,int update_locations)2798 gcc_jit_context_dump_to_file (gcc_jit_context *ctxt,
2799 const char *path,
2800 int update_locations)
2801 {
2802 RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
2803 JIT_LOG_FUNC (ctxt->get_logger ());
2804 RETURN_IF_FAIL (path, ctxt, NULL, "NULL path");
2805 ctxt->dump_to_file (path, update_locations);
2806 }
2807
2808 /* Public entrypoint. See description in libgccjit.h. */
2809
2810 void
gcc_jit_context_set_logfile(gcc_jit_context * ctxt,FILE * logfile,int flags,int verbosity)2811 gcc_jit_context_set_logfile (gcc_jit_context *ctxt,
2812 FILE *logfile,
2813 int flags,
2814 int verbosity)
2815 {
2816 RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
2817 JIT_LOG_FUNC (ctxt->get_logger ());
2818 RETURN_IF_FAIL ((flags == 0), ctxt, NULL, "flags must be 0 for now");
2819 RETURN_IF_FAIL ((verbosity == 0), ctxt, NULL, "verbosity must be 0 for now");
2820
2821 gcc::jit::logger *logger;
2822 if (logfile)
2823 logger = new gcc::jit::logger (logfile, flags, verbosity);
2824 else
2825 logger = NULL;
2826 ctxt->set_logger (logger);
2827 }
2828
2829 /* Public entrypoint. See description in libgccjit.h.
2830
2831 After error-checking, the real work is done by the
2832 gcc::jit::recording::context::dump_reproducer_to_file method in
2833 jit-recording.c. */
2834
2835 void
gcc_jit_context_dump_reproducer_to_file(gcc_jit_context * ctxt,const char * path)2836 gcc_jit_context_dump_reproducer_to_file (gcc_jit_context *ctxt,
2837 const char *path)
2838 {
2839 RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
2840 JIT_LOG_FUNC (ctxt->get_logger ());
2841 RETURN_IF_FAIL (path, ctxt, NULL, "NULL path");
2842 ctxt->dump_reproducer_to_file (path);
2843 }
2844
2845 /* Public entrypoint. See description in libgccjit.h.
2846
2847 After error-checking, the real work is done by the
2848 gcc::jit::recording::context::get_first_error method in
2849 jit-recording.c. */
2850
2851 const char *
gcc_jit_context_get_first_error(gcc_jit_context * ctxt)2852 gcc_jit_context_get_first_error (gcc_jit_context *ctxt)
2853 {
2854 RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
2855 JIT_LOG_FUNC (ctxt->get_logger ());
2856
2857 return ctxt->get_first_error ();
2858 }
2859
2860 /* Public entrypoint. See description in libgccjit.h.
2861
2862 After error-checking, the real work is done by the
2863 gcc::jit::recording::context::get_last_error method in
2864 jit-recording.c. */
2865
2866 const char *
gcc_jit_context_get_last_error(gcc_jit_context * ctxt)2867 gcc_jit_context_get_last_error (gcc_jit_context *ctxt)
2868 {
2869 RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
2870
2871 return ctxt->get_last_error ();
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::result::get_code method in jit-result.c. */
2878
2879 void *
gcc_jit_result_get_code(gcc_jit_result * result,const char * fnname)2880 gcc_jit_result_get_code (gcc_jit_result *result,
2881 const char *fnname)
2882 {
2883 RETURN_NULL_IF_FAIL (result, NULL, NULL, "NULL result");
2884 JIT_LOG_FUNC (result->get_logger ());
2885 RETURN_NULL_IF_FAIL (fnname, NULL, NULL, "NULL fnname");
2886
2887 result->log ("locating fnname: %s", fnname);
2888 void *code = result->get_code (fnname);
2889 result->log ("%s: returning (void *)%p", __func__, code);
2890
2891 return code;
2892 }
2893
2894 /* Public entrypoint. See description in libgccjit.h.
2895
2896 After error-checking, the real work is done by the
2897 gcc::jit::result::get_global method in jit-result.c. */
2898
2899 void *
gcc_jit_result_get_global(gcc_jit_result * result,const char * name)2900 gcc_jit_result_get_global (gcc_jit_result *result,
2901 const char *name)
2902 {
2903 RETURN_NULL_IF_FAIL (result, NULL, NULL, "NULL result");
2904 JIT_LOG_FUNC (result->get_logger ());
2905 RETURN_NULL_IF_FAIL (name, NULL, NULL, "NULL name");
2906
2907 void *global = result->get_global (name);
2908 result->log ("%s: returning (void *)%p", __func__, global);
2909
2910 return global;
2911 }
2912
2913 /* Public entrypoint. See description in libgccjit.h.
2914
2915 After error-checking, this is essentially a wrapper around the
2916 destructor for gcc::jit::result in jit-result.c. */
2917
2918 void
gcc_jit_result_release(gcc_jit_result * result)2919 gcc_jit_result_release (gcc_jit_result *result)
2920 {
2921 RETURN_IF_FAIL (result, NULL, NULL, "NULL result");
2922 JIT_LOG_FUNC (result->get_logger ());
2923 result->log ("deleting result: %p", (void *)result);
2924 delete result;
2925 }
2926
2927 /**********************************************************************
2928 Timing support.
2929 **********************************************************************/
2930
2931 /* Create a gcc_jit_timer instance, and start timing. */
2932
2933 gcc_jit_timer *
gcc_jit_timer_new(void)2934 gcc_jit_timer_new (void)
2935 {
2936 gcc_jit_timer *timer = new gcc_jit_timer ();
2937 timer->start (TV_TOTAL);
2938 timer->push (TV_JIT_CLIENT_CODE);
2939 return timer;
2940 }
2941
2942 /* Release a gcc_jit_timer instance. */
2943
2944 void
gcc_jit_timer_release(gcc_jit_timer * timer)2945 gcc_jit_timer_release (gcc_jit_timer *timer)
2946 {
2947 RETURN_IF_FAIL (timer, NULL, NULL, "NULL timer");
2948
2949 delete timer;
2950 }
2951
2952 /* Associate a gcc_jit_timer instance with a context. */
2953
2954 void
gcc_jit_context_set_timer(gcc_jit_context * ctxt,gcc_jit_timer * timer)2955 gcc_jit_context_set_timer (gcc_jit_context *ctxt,
2956 gcc_jit_timer *timer)
2957 {
2958 RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL ctxt");
2959 RETURN_IF_FAIL (timer, ctxt, NULL, "NULL timer");
2960
2961 ctxt->set_timer (timer);
2962 }
2963
2964 /* Get the timer associated with a context (if any). */
2965
2966 gcc_jit_timer *
gcc_jit_context_get_timer(gcc_jit_context * ctxt)2967 gcc_jit_context_get_timer (gcc_jit_context *ctxt)
2968 {
2969 RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL ctxt");
2970
2971 return (gcc_jit_timer *)ctxt->get_timer ();
2972 }
2973
2974 /* Push the given item onto the timing stack. */
2975
2976 void
gcc_jit_timer_push(gcc_jit_timer * timer,const char * item_name)2977 gcc_jit_timer_push (gcc_jit_timer *timer,
2978 const char *item_name)
2979 {
2980 RETURN_IF_FAIL (timer, NULL, NULL, "NULL timer");
2981 RETURN_IF_FAIL (item_name, NULL, NULL, "NULL item_name");
2982 timer->push_client_item (item_name);
2983 }
2984
2985 /* Pop the top item from the timing stack. */
2986
2987 void
gcc_jit_timer_pop(gcc_jit_timer * timer,const char * item_name)2988 gcc_jit_timer_pop (gcc_jit_timer *timer,
2989 const char *item_name)
2990 {
2991 RETURN_IF_FAIL (timer, NULL, NULL, "NULL timer");
2992
2993 if (item_name)
2994 {
2995 const char *top_item_name = timer->get_topmost_item_name ();
2996
2997 RETURN_IF_FAIL_PRINTF1
2998 (top_item_name, NULL, NULL,
2999 "pop of empty timing stack (attempting to pop: \"%s\")",
3000 item_name);
3001
3002 RETURN_IF_FAIL_PRINTF2
3003 (strcmp (item_name, top_item_name) == 0, NULL, NULL,
3004 "mismatching item_name:"
3005 " top of timing stack: \"%s\","
3006 " attempting to pop: \"%s\"",
3007 top_item_name,
3008 item_name);
3009 }
3010
3011 timer->pop_client_item ();
3012 }
3013
3014 /* Print timing information to the given stream about activity since
3015 the timer was started. */
3016
3017 void
gcc_jit_timer_print(gcc_jit_timer * timer,FILE * f_out)3018 gcc_jit_timer_print (gcc_jit_timer *timer,
3019 FILE *f_out)
3020 {
3021 RETURN_IF_FAIL (timer, NULL, NULL, "NULL timer");
3022 RETURN_IF_FAIL (f_out, NULL, NULL, "NULL f_out");
3023
3024 timer->pop (TV_JIT_CLIENT_CODE);
3025 timer->stop (TV_TOTAL);
3026 timer->print (f_out);
3027 timer->start (TV_TOTAL);
3028 timer->push (TV_JIT_CLIENT_CODE);
3029 }
3030
3031 /* Public entrypoint. See description in libgccjit.h.
3032
3033 After error-checking, the real work is effectively done by the
3034 gcc::jit::base_call::set_require_tail_call setter in jit-recording.h. */
3035
3036 void
gcc_jit_rvalue_set_bool_require_tail_call(gcc_jit_rvalue * rvalue,int require_tail_call)3037 gcc_jit_rvalue_set_bool_require_tail_call (gcc_jit_rvalue *rvalue,
3038 int require_tail_call)
3039 {
3040 RETURN_IF_FAIL (rvalue, NULL, NULL, "NULL call");
3041 JIT_LOG_FUNC (rvalue->get_context ()->get_logger ());
3042
3043 /* Verify that it's a call. */
3044 gcc::jit::recording::base_call *call = rvalue->dyn_cast_base_call ();
3045 RETURN_IF_FAIL_PRINTF1 (call, NULL, NULL, "not a call: %s",
3046 rvalue->get_debug_string ());
3047
3048 call->set_require_tail_call (require_tail_call);
3049 }
3050
3051 /* Public entrypoint. See description in libgccjit.h.
3052
3053 After error-checking, the real work is done by the
3054 gcc::jit::recording::type::get_aligned method, in
3055 jit-recording.c. */
3056
3057 gcc_jit_type *
gcc_jit_type_get_aligned(gcc_jit_type * type,size_t alignment_in_bytes)3058 gcc_jit_type_get_aligned (gcc_jit_type *type,
3059 size_t alignment_in_bytes)
3060 {
3061 RETURN_NULL_IF_FAIL (type, NULL, NULL, "NULL type");
3062
3063 gcc::jit::recording::context *ctxt = type->m_ctxt;
3064
3065 JIT_LOG_FUNC (ctxt->get_logger ());
3066
3067 RETURN_NULL_IF_FAIL_PRINTF1
3068 (pow2_or_zerop (alignment_in_bytes), ctxt, NULL,
3069 "alignment not a power of two: %zi",
3070 alignment_in_bytes);
3071
3072 return (gcc_jit_type *)type->get_aligned (alignment_in_bytes);
3073 }
3074
3075 /* Public entrypoint. See description in libgccjit.h.
3076
3077 After error-checking, the real work is done by the
3078 gcc::jit::recording::type::get_vector method, in
3079 jit-recording.c. */
3080
3081 gcc_jit_type *
gcc_jit_type_get_vector(gcc_jit_type * type,size_t num_units)3082 gcc_jit_type_get_vector (gcc_jit_type *type, size_t num_units)
3083 {
3084 RETURN_NULL_IF_FAIL (type, NULL, NULL, "NULL type");
3085
3086 gcc::jit::recording::context *ctxt = type->m_ctxt;
3087
3088 JIT_LOG_FUNC (ctxt->get_logger ());
3089
3090 RETURN_NULL_IF_FAIL_PRINTF1
3091 (type->is_int () || type->is_float (), ctxt, NULL,
3092 "type is not integral or floating point: %s",
3093 type->get_debug_string ());
3094
3095 RETURN_NULL_IF_FAIL_PRINTF1
3096 (pow2_or_zerop (num_units), ctxt, NULL,
3097 "num_units not a power of two: %zi",
3098 num_units);
3099
3100 return (gcc_jit_type *)type->get_vector (num_units);
3101 }
3102
3103 /* Public entrypoint. See description in libgccjit.h.
3104
3105 After error-checking, the real work is done by the
3106 gcc::jit::recording::function::get_address method, in
3107 jit-recording.c. */
3108
3109 gcc_jit_rvalue *
gcc_jit_function_get_address(gcc_jit_function * fn,gcc_jit_location * loc)3110 gcc_jit_function_get_address (gcc_jit_function *fn,
3111 gcc_jit_location *loc)
3112 {
3113 RETURN_NULL_IF_FAIL (fn, NULL, NULL, "NULL function");
3114
3115 gcc::jit::recording::context *ctxt = fn->m_ctxt;
3116
3117 JIT_LOG_FUNC (ctxt->get_logger ());
3118 /* LOC can be NULL. */
3119
3120 return (gcc_jit_rvalue *)fn->get_address (loc);
3121 }
3122
3123 /* Public entrypoint. See description in libgccjit.h.
3124
3125 After error-checking, the real work is done by the
3126 gcc::jit::recording::context::new_rvalue_from_vector method, in
3127 jit-recording.c. */
3128
3129 extern gcc_jit_rvalue *
gcc_jit_context_new_rvalue_from_vector(gcc_jit_context * ctxt,gcc_jit_location * loc,gcc_jit_type * vec_type,size_t num_elements,gcc_jit_rvalue ** elements)3130 gcc_jit_context_new_rvalue_from_vector (gcc_jit_context *ctxt,
3131 gcc_jit_location *loc,
3132 gcc_jit_type *vec_type,
3133 size_t num_elements,
3134 gcc_jit_rvalue **elements)
3135 {
3136 RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL ctxt");
3137 JIT_LOG_FUNC (ctxt->get_logger ());
3138
3139 /* LOC can be NULL. */
3140 RETURN_NULL_IF_FAIL (vec_type, ctxt, loc, "NULL vec_type");
3141
3142 /* "vec_type" must be a vector type. */
3143 gcc::jit::recording::vector_type *as_vec_type
3144 = vec_type->dyn_cast_vector_type ();
3145 RETURN_NULL_IF_FAIL_PRINTF1 (as_vec_type, ctxt, loc,
3146 "%s is not a vector type",
3147 vec_type->get_debug_string ());
3148
3149 /* "num_elements" must match. */
3150 RETURN_NULL_IF_FAIL_PRINTF1 (
3151 num_elements == as_vec_type->get_num_units (), ctxt, loc,
3152 "num_elements != %zi", as_vec_type->get_num_units ());
3153
3154 /* "elements must be non-NULL. */
3155 RETURN_NULL_IF_FAIL (elements, ctxt, loc, "NULL elements");
3156
3157 /* Each of "elements" must be non-NULL and of the correct type. */
3158 gcc::jit::recording::type *element_type
3159 = as_vec_type->get_element_type ();
3160 for (size_t i = 0; i < num_elements; i++)
3161 {
3162 RETURN_NULL_IF_FAIL_PRINTF1 (
3163 elements[i], ctxt, loc, "NULL elements[%zi]", i);
3164 RETURN_NULL_IF_FAIL_PRINTF4 (
3165 compatible_types (element_type,
3166 elements[i]->get_type ()),
3167 ctxt, loc,
3168 "mismatching type for element[%zi] (expected type: %s): %s (type: %s)",
3169 i,
3170 element_type->get_debug_string (),
3171 elements[i]->get_debug_string (),
3172 elements[i]->get_type ()->get_debug_string ());
3173 }
3174
3175 return (gcc_jit_rvalue *)ctxt->new_rvalue_from_vector
3176 (loc,
3177 as_vec_type,
3178 (gcc::jit::recording::rvalue **)elements);
3179 }
3180
3181 /* A mutex around the cached state in parse_basever.
3182 Ideally this would be within parse_basever, but the mutex is only needed
3183 by libgccjit. */
3184
3185 static pthread_mutex_t version_mutex = PTHREAD_MUTEX_INITIALIZER;
3186
3187 struct version_info
3188 {
3189 /* Default constructor. Populate via parse_basever,
3190 guarded by version_mutex. */
version_infoversion_info3191 version_info ()
3192 {
3193 pthread_mutex_lock (&version_mutex);
3194 parse_basever (&major, &minor, &patchlevel);
3195 pthread_mutex_unlock (&version_mutex);
3196 }
3197
3198 int major;
3199 int minor;
3200 int patchlevel;
3201 };
3202
3203
3204 extern int
gcc_jit_version_major(void)3205 gcc_jit_version_major (void)
3206 {
3207 version_info vi;
3208 return vi.major;
3209 }
3210
3211 extern int
gcc_jit_version_minor(void)3212 gcc_jit_version_minor (void)
3213 {
3214 version_info vi;
3215 return vi.minor;
3216 }
3217
3218 extern int
gcc_jit_version_patchlevel(void)3219 gcc_jit_version_patchlevel (void)
3220 {
3221 version_info vi;
3222 return vi.patchlevel;
3223 }
3224