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