From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from sender4-pp-o91.zoho.com (sender4-pp-o91.zoho.com [136.143.188.91]) by sourceware.org (Postfix) with ESMTPS id C5FE13858004; Wed, 26 May 2021 00:19:58 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org C5FE13858004 ARC-Seal: i=1; a=rsa-sha256; t=1621988395; cv=none; d=zohomail.com; s=zohoarc; b=fGeGeDnFxKhANoLmob5aAsT8Qi85xrJbLEzmquYAiGG//SQsVsuJCEmC8J3zfUlQOj4VJAFvj6/MDAf7LatzyPO4tqucz7s03d9fzIQazk6HhgK8ZECzLtJq4wSWMRra3VBimgFYdseMefcYR2m+Me2dHq+AB9UQxgCSwUDJFX4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1621988395; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:MIME-Version:Message-ID:References:Subject:To; bh=+HjaiJahbYxboSkR0LsK5Dfc657oRKHfUq4QRmYcjlE=; b=bxbpSo8LeJho4EJWTVcYmiQdFjaW+pEm0MzCulZP6qaQWrZ68Kpla6io4LaGWqEozGH/J8zcCAbfdwDWBcKYdeWBPb5kFf9wlMB3eSpWQZcv9tvgduO7iIB8AOMU2loyl6KPZlKkGpQUNllpawMXQF7qtGuokMYkje5EMI2lSMk= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=zoho.com; spf=pass smtp.mailfrom=bouanto@zoho.com; dmarc=pass header.from= Received: from [192.168.1.174] (38.87.11.6 [38.87.11.6]) by mx.zohomail.com with SMTPS id 1621988391763813.0696965587963; Tue, 25 May 2021 17:19:51 -0700 (PDT) Message-ID: <0e8b6450bcb23182b85342d8010c3bea0c297ba2.camel@zoho.com> Subject: Re: [PATCH] libgccjit: add some reflection functions in the jit C api From: Antoni Boucher To: David Malcolm Cc: Andrea Corallo , Antoni Boucher via Jit , gcc-patches@gcc.gnu.org Date: Tue, 25 May 2021 20:19:49 -0400 In-Reply-To: <3388bb8c84e68cd7b0698dc154e7a5666c0d2cde.camel@redhat.com> References: <20200902010120.crnx55ev635ceiey@bouanto-desktop.localdomain> <6fe2ea355403eb177c9632e076c11c792f23c791.camel@redhat.com> <9cd00fe5cb5c03184e3a5bd939447b30450a8ca7.camel@redhat.com> <20201015160226.cka4iq3w22jztopm@bouanto-desktop.localdomain> <20201015173952.ft7mu5ajbaxb3gke@bouanto-desktop.localdomain> <54ba5c58dbd2b8c7b1f3276c2b87cddf55e258bd.camel@redhat.com> <20201103221324.xw3jbvrw2uwdc4rz@bouanto-desktop.localdomain> <3388bb8c84e68cd7b0698dc154e7a5666c0d2cde.camel@redhat.com> Content-Type: text/plain; charset="UTF-8" User-Agent: Evolution 3.40.1 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMailClient: External X-Spam-Status: No, score=-11.2 required=5.0 tests=BAYES_00, BODY_8BITS, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: jit@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Jit mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 26 May 2021 00:20:03 -0000 @David: PING As far as I know, the only remaining question is about using `ssize_t` for the return type of some functions. Here's why I use this type: That seemed off to return NULL for the functions returning a=20 size_t to indicate an error. So I changed it to return -1 (and return type to ssize_t). Is that the proper way to indicate an error? Once I know the answer for this error handling question, I'll fix the types. Thanks! Le jeudi 13 mai 2021 =C3=A0 17:30 -0400, David Malcolm a =C3=A9crit=C2=A0: > On Tue, 2020-11-03 at 17:13 -0500, Antoni Boucher wrote: > > I was missing a check in gcc_jit_struct_get_field, I added it in this > > new patch. > >=20 >=20 > Sorry about the long delay in reviewing this patch. >=20 > The main high-level points are: > - currently the get_*_count functions return "ssize_t" - why?=C2=A0 Only > unsigned values are meaningful; shouldn't they return "size_t" instead? >=20 > - the various "lookup by index" functions take "int" i.e. signed, but > only >=3D 0 is meaningful.=C2=A0 I think it makes sense to make them take > size_t instead. >=20 > Sorry if we covered that before in the review, it's been a while. >=20 > Various nitpicks inline below... >=20 > [...snip...] > =C2=A0 > > diff --git a/gcc/jit/docs/topics/compatibility.rst > > b/gcc/jit/docs/topics/compatibility.rst > > index 6bfa101ed71..236e5c72d81 100644 > > --- a/gcc/jit/docs/topics/compatibility.rst > > +++ b/gcc/jit/docs/topics/compatibility.rst > > @@ -226,3 +226,44 @@ entrypoints: > > =C2=A0-------------------- > > =C2=A0``LIBGCCJIT_ABI_14`` covers the addition of > > =C2=A0:func:`gcc_jit_global_set_initializer` > > + > > +.. _LIBGCCJIT_ABI_15: > > + > > +``LIBGCCJIT_ABI_15`` > > +-------------------- > > +``LIBGCCJIT_ABI_15`` covers the addition of reflection functions via > > API > > +entrypoints: >=20 > This needs updating, as I used LIBGCCJIT_ABI_15 for inline asm. >=20 > [...snip...] >=20 > > diff --git a/gcc/jit/docs/topics/functions.rst > > b/gcc/jit/docs/topics/functions.rst > > index eb40d64010e..aa6de87282d 100644 > > --- a/gcc/jit/docs/topics/functions.rst > > +++ b/gcc/jit/docs/topics/functions.rst > > @@ -171,6 +171,16 @@ Functions > > =C2=A0=C2=A0=C2=A0 underlying string, so it is valid to pass in a point= er to an on- > > stack > > =C2=A0=C2=A0=C2=A0 buffer. > > =C2=A0 > > +.. function::=C2=A0 ssize_t \ > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0 gcc_jit_function_get_param_count (gcc_jit_function > > *func) > > + > > +=C2=A0=C2=A0 Get the number of parameters of the function. > > + > > +.. function::=C2=A0 gcc_jit_type \* > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0 gcc_jit_function_get_return_type (gcc_jit_function > > *func) > > + > > +=C2=A0=C2=A0 Get the return type of the function. >=20 > As noted before, this doesn't yet document all the new entrypoints; I > think you wanted to hold off until all the details were thrashed out, > but hopefully we're close. >=20 > The documentation for an entrypoint should specify which ABI it was > added in. >=20 > [...snip...] >=20 > > +/* Public entrypoint.=C2=A0 See description in libgccjit.h. > > + > > +=C2=A0=C2=A0 After error-checking, the real work is done by the > > +=C2=A0=C2=A0 gcc::jit::recording::type::is_struct method, in > > +=C2=A0=C2=A0 jit-recording.c.=C2=A0 */ > > + > > +gcc_jit_struct * > > +gcc_jit_type_is_struct (gcc_jit_type *type) > > +{ > > +=C2=A0 RETURN_NULL_IF_FAIL (type, NULL, NULL, "NULL type"); > > +=C2=A0 gcc::jit::recording::struct_ *struct_type =3D type->is_struct (= ); > > +=C2=A0 return (gcc_jit_struct *)struct_type; > > +} > > + > > +/* Public entrypoint.=C2=A0 See description in libgccjit.h. > > + > > +=C2=A0=C2=A0 After error-checking, the real work is done by the > > +=C2=A0=C2=A0 gcc::jit::recording::vector_type::get_num_units method, i= n > > +=C2=A0=C2=A0 jit-recording.c.=C2=A0 */ > > + > > +ssize_t > > +gcc_jit_vector_type_get_num_units (gcc_jit_vector_type *vector_type) > > +{ > > +=C2=A0 RETURN_VAL_IF_FAIL (vector_type, -1, NULL, NULL, "NULL > > vector_type"); > > +=C2=A0 return vector_type->get_num_units (); > > +} > > + > > +/* Public entrypoint.=C2=A0 See description in libgccjit.h. > > + > > +=C2=A0=C2=A0 After error-checking, the real work is done by the > > +=C2=A0=C2=A0 gcc::jit::recording::vector_type::get_element_type method= , in > > +=C2=A0=C2=A0 jit-recording.c.=C2=A0 */ > > + > > +gcc_jit_type * > > +gcc_jit_vector_type_get_element_type (gcc_jit_vector_type > > *vector_type) > > +{ > > +=C2=A0 RETURN_NULL_IF_FAIL (vector_type, NULL, NULL, "NULL vector_type= "); > > +=C2=A0 return (gcc_jit_type *)vector_type->get_element_type (); > > +} > > + > > +/* Public entrypoint.=C2=A0 See description in libgccjit.h. > > + > > +=C2=A0=C2=A0 After error-checking, the real work is done by the > > +=C2=A0=C2=A0 gcc::jit::recording::type::unqualified method, in > > +=C2=A0=C2=A0 jit-recording.c.=C2=A0 */ > > + > > +gcc_jit_type * > > +gcc_jit_type_unqualified (gcc_jit_type *type) > > +{ > > +=C2=A0 RETURN_NULL_IF_FAIL (type, NULL, NULL, "NULL type"); > > + > > +=C2=A0 return (gcc_jit_type *)type->unqualified (); > > +} > > + > > +/* Public entrypoint.=C2=A0 See description in libgccjit.h. > > + > > +=C2=A0=C2=A0 After error-checking, the real work is done by the > > +=C2=A0=C2=A0 gcc::jit::recording::type::dyn_cast_function_type method,= in > > +=C2=A0=C2=A0 jit-recording.c.=C2=A0 */ > > + > > +gcc_jit_function_type * > > +gcc_jit_type_is_function_ptr_type (gcc_jit_type *type) > > +{ > > +=C2=A0 RETURN_NULL_IF_FAIL (type, NULL, NULL, "NULL type"); > > +=C2=A0 gcc::jit::recording::type *func_ptr_type =3D type->dereference = (); > > +=C2=A0 RETURN_NULL_IF_FAIL (func_ptr_type, NULL, NULL, "NULL type"); > > +=C2=A0 gcc::jit::recording::function_type *func_type =3D > > +=C2=A0=C2=A0=C2=A0 func_ptr_type->dyn_cast_function_type (); > > +=C2=A0 RETURN_NULL_IF_FAIL (func_type, NULL, NULL, "NULL type"); >=20 > I notice that the other new "*_is_*" functions don't fail if the > dyncast returns NULL, whereas this one does. >=20 > RETURN_NULL_IF_FAIL calls jit_error; do we really want that?=C2=A0 It see= ms > more consistent to have it return NULL without an error for the case > where "type" isn't a function ptr type. >=20 > > + > > +=C2=A0 return (gcc_jit_function_type *)func_type; > > +} > > + > > +/* Public entrypoint.=C2=A0 See description in libgccjit.h. > > + > > +=C2=A0=C2=A0 After error-checking, the real work is done by the > > +=C2=A0=C2=A0 gcc::jit::recording::function_type::get_return_type metho= d, in > > +=C2=A0=C2=A0 jit-recording.c.=C2=A0 */ > > + > > +gcc_jit_type * > > +gcc_jit_function_type_get_return_type (gcc_jit_function_type > > *function_type) > > +{ > > +=C2=A0 RETURN_NULL_IF_FAIL (function_type, NULL, NULL, "NULL > > struct_type"); >=20 > Wrong error message; should be "NULL function_type". >=20 >=20 > > +=C2=A0 return (gcc_jit_type *)function_type->get_return_type (); > > +} > > + > > +/* Public entrypoint.=C2=A0 See description in libgccjit.h. > > + > > +=C2=A0=C2=A0 After error-checking, the real work is done by the > > +=C2=A0=C2=A0 gcc::jit::recording::function_type::get_param_types metho= d, in > > +=C2=A0=C2=A0 jit-recording.c.=C2=A0 */ > > + > > +ssize_t > > +gcc_jit_function_type_get_param_count (gcc_jit_function_type > > *function_type) > > +{ > > +=C2=A0 RETURN_VAL_IF_FAIL (function_type, -1, NULL, NULL, "NULL > > struct_type"); >=20 > Wrong error message; should be "NULL function_type". >=20 > > +=C2=A0 return function_type->get_param_types ().length (); > > +} > > + > > +/* Public entrypoint.=C2=A0 See description in libgccjit.h. > > + > > +=C2=A0=C2=A0 After error-checking, the real work is done by the > > +=C2=A0=C2=A0 gcc::jit::recording::function_type::get_param_types metho= d, in > > +=C2=A0=C2=A0 jit-recording.c.=C2=A0 */ > > + > > +gcc_jit_type * > > +gcc_jit_function_type_get_param_type (gcc_jit_function_type > > *function_type, > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0int index) > > +{ > > +=C2=A0 RETURN_NULL_IF_FAIL (function_type, NULL, NULL, "NULL > > struct_type"); >=20 > Wrong error message; should be "NULL function_type". >=20 >=20 > > +=C2=A0 int num_params =3D function_type->get_param_types ().length (); > > +=C2=A0 gcc::jit::recording::context *ctxt =3D function_type->m_ctxt; >=20 > "index" should either be unsigned, or we need to check here for >=3D 0. >=20 > > +=C2=A0 RETURN_NULL_IF_FAIL_PRINTF3 (index < num_params, > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ctxt, NULL, > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 "index of %d is too large (%s has %d > > params)", > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 index, > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 function_type->get_debug_string (), > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 num_params); > > +=C2=A0 return (gcc_jit_type *)function_type->get_param_types ()[index]= ; > > +} > > + > > =C2=A0/* Public entrypoint.=C2=A0 See description in libgccjit.h. > > =C2=A0 > > =C2=A0=C2=A0=C2=A0 After error-checking, the real work is done by the > > @@ -731,6 +930,36 @@ gcc_jit_struct_set_fields (gcc_jit_struct > > *struct_type, > > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0 (gcc::jit::recording::field **)fields); > > =C2=A0} > > =C2=A0 > > + > > +/* Public entrypoint.=C2=A0 See description in libgccjit.h. > > + > > +=C2=A0=C2=A0 After error-checking, the real work is done by the > > +=C2=A0=C2=A0 gcc::jit::recording::fields::get_field method in > > +=C2=A0=C2=A0 jit-recording.c.=C2=A0 */ > > +extern gcc_jit_field * > > +gcc_jit_struct_get_field (gcc_jit_struct *struct_type, > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0 int index) > > +{ > > +=C2=A0 RETURN_NULL_IF_FAIL (struct_type, NULL, NULL, "NULL struct type= "); > > +=C2=A0 RETURN_NULL_IF_FAIL (struct_type->get_fields (), NULL, NULL, "N= ULL > > struct fields"); >=20 > "index" should either be unsigned, or we need to check here for >=3D 0. >=20 > > +=C2=A0 RETURN_NULL_IF_FAIL (index < struct_type->get_fields ()->length > > (), NULL, > > +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0NULL, "NULL struct type"); > > +=C2=A0 return (gcc_jit_field *)struct_type->get_fields ()->get_field > > (index); > > +} >=20 > [...snip...] >=20 > > diff --git a/gcc/jit/libgccjit.h b/gcc/jit/libgccjit.h > > index 7134841bb07..db4ccffb41c 100644 > > --- a/gcc/jit/libgccjit.h > > +++ b/gcc/jit/libgccjit.h > > @@ -96,6 +96,12 @@ typedef struct gcc_jit_field gcc_jit_field; > > =C2=A0=C2=A0=C2=A0 the layout for, or an opaque type.=C2=A0 */ > > =C2=A0typedef struct gcc_jit_struct gcc_jit_struct; > > =C2=A0 > > +/* A gcc_jit_function_type encapsulates a function type.=C2=A0 */ > > +typedef struct gcc_jit_function_type gcc_jit_function_type; > > + > > +/* A gcc_jit_vector_type encapsulates a vector type.=C2=A0 */ > > +typedef struct gcc_jit_vector_type gcc_jit_vector_type; > > + >=20 > Please add these to the ASCII art inheritance diagram immediately > above: > =C2=A0 typedef struct gcc_jit_object gcc_jit_object; >=20 > [...snip...] >=20 > > =C2=A0/* Unions work similarly to structs.=C2=A0 */ > > =C2=A0extern gcc_jit_type * > > =C2=A0gcc_jit_context_new_union_type (gcc_jit_context *ctxt, > > @@ -1518,6 +1533,78 @@ gcc_jit_version_minor (void); > > =C2=A0extern int > > =C2=A0gcc_jit_version_patchlevel (void); > > =C2=A0 > > +#define LIBGCCJIT_HAVE_REFLECTION > > + > > +/* Reflection functions to get the number of parameters, return type > > of > > +=C2=A0=C2=A0 a function and whether a type is a bool from the C API. > > + > > +=C2=A0=C2=A0 This API entrypoint was added in LIBGCCJIT_ABI_15; you ca= n test > > for its > > +=C2=A0=C2=A0 presence using > > +=C2=A0=C2=A0=C2=A0=C2=A0 #ifdef LIBGCCJIT_HAVE_REFLECTION > > +*/ > > +/* Get the return type of a function.=C2=A0 */ > > +extern gcc_jit_type * > > +gcc_jit_function_get_return_type (gcc_jit_function *func); > > + > > +/* Get the number of params of a function.=C2=A0 */ > > +extern ssize_t > > +gcc_jit_function_get_param_count (gcc_jit_function *func); >=20 > You're using ssize_t here, why?=C2=A0 Wouldn't size_t be better? > The count can't be negative. >=20 > Should we use size_t for indexes, rather than "int"? >=20 > (this happens in various places e.g. > gcc_jit_function_type_get_param_count and > gcc_jit_vector_type_get_num_units) >=20 > [...snip...] >=20 > > diff --git a/gcc/jit/libgccjit.map b/gcc/jit/libgccjit.map > > index a6e67e781a4..720b6ca286f 100644 > > --- a/gcc/jit/libgccjit.map > > +++ b/gcc/jit/libgccjit.map > > @@ -192,3 +192,24 @@ LIBGCCJIT_ABI_14 { > > =C2=A0=C2=A0 global: > > =C2=A0=C2=A0=C2=A0=C2=A0 gcc_jit_global_set_initializer; > > =C2=A0} LIBGCCJIT_ABI_13; > > + > > +LIBGCCJIT_ABI_15 { > > +=C2=A0 global: > > +=C2=A0=C2=A0=C2=A0 gcc_jit_function_get_return_type; > > +=C2=A0=C2=A0=C2=A0 gcc_jit_function_get_param_count; > > +=C2=A0=C2=A0=C2=A0 gcc_jit_function_type_get_return_type; > > +=C2=A0=C2=A0=C2=A0 gcc_jit_function_type_get_param_count; > > +=C2=A0=C2=A0=C2=A0 gcc_jit_function_type_get_param_type; > > +=C2=A0=C2=A0=C2=A0 gcc_jit_type_unqualified; > > +=C2=A0=C2=A0=C2=A0 gcc_jit_type_is_array; > > +=C2=A0=C2=A0=C2=A0 gcc_jit_type_is_bool; > > +=C2=A0=C2=A0=C2=A0 gcc_jit_type_is_function_ptr_type; > > +=C2=A0=C2=A0=C2=A0 gcc_jit_type_is_integral; > > +=C2=A0=C2=A0=C2=A0 gcc_jit_type_is_pointer; > > +=C2=A0=C2=A0=C2=A0 gcc_jit_type_is_vector; > > +=C2=A0=C2=A0=C2=A0 gcc_jit_vector_type_get_element_type; > > +=C2=A0=C2=A0=C2=A0 gcc_jit_vector_type_get_num_units; > > +=C2=A0=C2=A0=C2=A0 gcc_jit_struct_get_field; > > +=C2=A0=C2=A0=C2=A0 gcc_jit_type_is_struct; > > +=C2=A0=C2=A0=C2=A0 gcc_jit_struct_get_field_count; > > +} LIBGCCJIT_ABI_14; >=20 > As noted above, this will need to be LIBGCCJIT_ABI_16 as I used > LIBGCCJIT_ABI_15 for inline asm. >=20 > [...snip...] >=20 > > diff --git a/gcc/testsuite/jit.dg/test-reflection.c > > b/gcc/testsuite/jit.dg/test-reflection.c > > new file mode 100644 > > index 00000000000..b3cf2942f3a > > --- /dev/null > > +++ b/gcc/testsuite/jit.dg/test-reflection.c > > @@ -0,0 +1,89 @@ > > +#include > > +#include > > + > > +#include "libgccjit.h" > > + > > +#include "harness.h" > > + > > +void > > +create_code (gcc_jit_context *ctxt, void *user_data) > > +{ > > +=C2=A0 /* Do nothing.=C2=A0 */ > > +} > > + > > +void > > +verify_code (gcc_jit_context *ctxt, gcc_jit_result *result) > > +{ > > +=C2=A0 /* Get the built-in functions.=C2=A0 */ > > +=C2=A0 gcc_jit_function *builtin_sin =3D > > +=C2=A0=C2=A0=C2=A0 gcc_jit_context_get_builtin_function (ctxt, "sin"); > > + > > +=C2=A0 CHECK_VALUE (gcc_jit_function_get_param_count(builtin_sin), 1); > > + > > +=C2=A0 gcc_jit_type *double_type =3D > > +=C2=A0=C2=A0=C2=A0 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_DOUBLE= ); > > +=C2=A0 CHECK_VALUE (gcc_jit_function_get_return_type(builtin_sin), > > double_type); > > +=C2=A0 CHECK (!gcc_jit_type_is_integral(double_type)); > > + > > +=C2=A0 gcc_jit_type *bool_type =3D > > +=C2=A0=C2=A0=C2=A0 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_BOOL); > > +=C2=A0 CHECK (gcc_jit_type_is_bool(bool_type)); > > +=C2=A0 CHECK (!gcc_jit_type_is_integral(bool_type)); > > + > > +=C2=A0 gcc_jit_type *aligned_bool_type =3D > > +=C2=A0=C2=A0=C2=A0 gcc_jit_type_get_aligned(gcc_jit_context_get_type (= ctxt, > > GCC_JIT_TYPE_BOOL), 8); > > +=C2=A0 CHECK (gcc_jit_type_is_bool(aligned_bool_type)); > > +=C2=A0 CHECK (bool_type !=3D aligned_bool_type); > > +=C2=A0 CHECK_VALUE (gcc_jit_type_unqualified(aligned_bool_type), > > bool_type); > > + > > +=C2=A0 CHECK_VALUE > > (gcc_jit_type_unqualified(gcc_jit_type_get_const(bool_type)), > > bool_type); > > +=C2=A0 CHECK_VALUE > > (gcc_jit_type_unqualified(gcc_jit_type_get_volatile(bool_type)), > > bool_type); > > + > > +=C2=A0 gcc_jit_type *int64 =3D > > +=C2=A0=C2=A0=C2=A0 gcc_jit_context_get_int_type(ctxt, 8, 1); > > +=C2=A0 CHECK (gcc_jit_type_is_integral(int64)); > > +=C2=A0 gcc_jit_type *uint64 =3D > > +=C2=A0=C2=A0=C2=A0 gcc_jit_context_get_int_type(ctxt, 8, 0); > > +=C2=A0 CHECK (gcc_jit_type_is_integral(uint64)); > > +=C2=A0 gcc_jit_type *int8 =3D > > +=C2=A0=C2=A0=C2=A0 gcc_jit_context_get_int_type(ctxt, 1, 1); > > +=C2=A0 CHECK (gcc_jit_type_is_integral(int8)); > > +=C2=A0 gcc_jit_type *uint8 =3D > > +=C2=A0=C2=A0=C2=A0 gcc_jit_context_get_int_type(ctxt, 1, 0); > > +=C2=A0 CHECK (gcc_jit_type_is_integral(uint8)); > > + > > +=C2=A0 CHECK (!gcc_jit_type_is_vector(double_type)); > > +=C2=A0 gcc_jit_type *vec_type =3D gcc_jit_type_get_vector (double_type= , 4); > > +=C2=A0 gcc_jit_vector_type *vector_type =3D > > gcc_jit_type_is_vector(vec_type); > > +=C2=A0 CHECK (vector_type); > > +=C2=A0 CHECK (vec_type !=3D double_type); > > +=C2=A0 CHECK_VALUE (gcc_jit_vector_type_get_element_type(vector_type), > > double_type); > > +=C2=A0 CHECK_VALUE (gcc_jit_vector_type_get_num_units(vector_type), 4)= ; > > + > > +=C2=A0 CHECK (!gcc_jit_type_is_pointer(double_type)); > > +=C2=A0 CHECK_VALUE > > (gcc_jit_type_is_pointer(gcc_jit_type_get_pointer(double_type)), > > double_type); > > + > > +=C2=A0 gcc_jit_type* params[2] =3D {int8, uint64}; > > +=C2=A0 gcc_jit_type *function_ptr_type =3D > > gcc_jit_context_new_function_ptr_type(ctxt, NULL, int64, 2, params, > > 0); > > +=C2=A0 gcc_jit_function_type *function_type =3D > > gcc_jit_type_is_function_ptr_type (function_ptr_type); > > +=C2=A0 CHECK (function_type); > > +=C2=A0 int param_count =3D > > gcc_jit_function_type_get_param_count(function_type); > > +=C2=A0 CHECK_VALUE (param_count, 2); > > +=C2=A0 gcc_jit_type *return_type =3D > > gcc_jit_function_type_get_return_type(function_type); > > +=C2=A0 CHECK_VALUE (return_type, int64); > > +=C2=A0 gcc_jit_type *param1 =3D > > gcc_jit_function_type_get_param_type(function_type, 0); > > +=C2=A0 CHECK_VALUE (param1, int8); > > +=C2=A0 gcc_jit_type *param2 =3D > > gcc_jit_function_type_get_param_type(function_type, 1); > > +=C2=A0 CHECK_VALUE (param2, uint64); > > + > > +=C2=A0 gcc_jit_field *field1 =3D gcc_jit_context_new_field (ctxt, NULL= , > > uint64, "field1"); > > +=C2=A0 gcc_jit_field *field2 =3D gcc_jit_context_new_field (ctxt, NULL= , > > double_type, "field2"); > > +=C2=A0 gcc_jit_field *fields[2] =3D { field1, field2 }; > > +=C2=A0 gcc_jit_struct *struct_type =3D gcc_jit_context_new_struct_type > > (ctxt, NULL, "testStruct", 2, fields); > > +=C2=A0 CHECK_VALUE (gcc_jit_struct_get_field_count(struct_type), 2); > > +=C2=A0 CHECK_VALUE (gcc_jit_struct_get_field(struct_type, 0), field1); > > +=C2=A0 CHECK_VALUE (gcc_jit_struct_get_field(struct_type, 1), field2); > > +=C2=A0 gcc_jit_struct *struct_ty =3D > > gcc_jit_type_is_struct(gcc_jit_struct_as_type(struct_type)); > > +=C2=A0 CHECK_VALUE (struct_ty, struct_type); >=20 >=20 > I think this is missing test coverage for the various gcc_jit_type_is_* > entrypoints gracefully returning NULL when the type passed to them is > wrong (e.g. a non-struct type passed to gcc_jit_type_is_struct, etc) >=20 > Hope this is constructive; sorry again about the delay in reviewing it. > Dave >=20 >=20