LCOV - code coverage report
Current view: top level - gcc/jit - libgccjit.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 96.5 % 1318 1272
Test Date: 2026-06-20 15:32:29 Functions: 95.0 % 179 170
Legend: Lines:     hit not hit

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

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.