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