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