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