public inbox for jit@gcc.gnu.org
 help / color / mirror / Atom feed
From: Joseph Jevnik <joejev@gmail.com>
To: jit@gcc.gnu.org
Subject: small C++ API additions
Date: Sun, 01 Jan 2017 00:00:00 -0000	[thread overview]
Message-ID: <CAHGq92XQ2_jZYodi=UoW0nUTPmduq-A9H5uRcj5GdtCQwoonhQ@mail.gmail.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 1615 bytes --]

Hello all,

I have been playing around with the C++ wrapper for gccjit and have noticed a
few things missing from the C API. I have written up four small patches to add
the missing features.

The patches include the following changes:

new-function-ptr-type.patch: Adds a method on 'context' to create a new function
pointer type.

new-union-type.patch: Adds a method on 'context' for creating a new union
type. This also adds a 'union_' class like 'struct_' which subclasses 'type'.

set_fields.patch: Adds a method to 'struct_' for setting the fields of an opaque
struct type. The C++ wrapper already allowed creation of opaque structs but
didn't have a way to populate them for creating recusive structures like linked
lists.

operator-call.patch: Adds a variadic dispatch for 'function::operator()' when
compiling with C++11 support. This extends 'function(a, b, c, ...) for arbitrary
amounts of arguments without needing to create a vector to pass the arguments
in. Right now this just dispatches through the vector case but could be changed
to use a 'std::array<rvalue, sizeof...(Args)>' in the future. This is mostly
just to simplify the API for fixed arity calls which have a lot of arguments.

Currently all of these patches are missing tests. I found the C tests but didn't
see anything for the C++ API. I would love to add some cases for these but I
just don't know where to look.

This is my first time posting to any of the GCC mailing lists or working on GCC
at all so please let me know if this is not the correct place to post this or if
I have done something incorrectly.

Thank you for your time!

[-- Attachment #2: new-function-ptr-type.patch --]
[-- Type: text/x-patch, Size: 1654 bytes --]

diff --git a/gcc/jit/libgccjit++.h b/gcc/jit/libgccjit++.h
index 8dc2112367b..a6d531dc697 100644
--- a/gcc/jit/libgccjit++.h
+++ b/gcc/jit/libgccjit++.h
@@ -169,6 +169,11 @@ namespace gccjit
 			   int is_variadic,
 			   location loc = location ());
 
+   type new_function_ptr_type (type return_type,
+                               std::vector<type> &params,
+                               int is_variadic,
+                               location loc = location ());
+
     function get_builtin_function (const std::string &name);
 
     lvalue new_global (enum gcc_jit_global_kind kind,
@@ -810,6 +815,29 @@ context::new_function (enum gcc_jit_function_kind kind,
 						 is_variadic));
 }
 
+inline type
+context::new_function_ptr_type (type return_type,
+                                std::vector<type> &params,
+                                int is_variadic,
+                                location loc)
+{
+  /* Treat std::vector as an array, relying on it not being resized: */
+  type *as_array_of_wrappers = params.data();
+
+  /* Treat the array as being of the underlying pointers, relying on
+     the wrapper type being such a pointer internally.	*/
+  gcc_jit_type **as_array_of_ptrs =
+    reinterpret_cast<gcc_jit_type **> (as_array_of_wrappers);
+
+  return type (gcc_jit_context_new_function_ptr_type (
+                   m_inner_ctxt,
+                   loc.get_inner_location (),
+                   return_type.get_inner_type (),
+                   params.size (),
+                   as_array_of_ptrs,
+                   is_variadic));
+}
+
 inline function
 context::get_builtin_function (const std::string &name)
 {

[-- Attachment #3: new-union-type.patch --]
[-- Type: text/x-patch, Size: 2423 bytes --]

diff --git a/gcc/jit/libgccjit++.h b/gcc/jit/libgccjit++.h
index 8dc2112367b..5a7bf8e2c43 100644
--- a/gcc/jit/libgccjit++.h
+++ b/gcc/jit/libgccjit++.h
@@ -40,6 +40,7 @@ namespace gccjit
     class field;
     class type;
       class struct_;
+      class union_;
     class function;
     class block;
     class rvalue;
@@ -158,6 +159,10 @@ namespace gccjit
     struct_ new_opaque_struct_type (const std::string &name,
 				    location loc = location ());
 
+    union_ new_union_type (const std::string &name,
+                           std::vector<field> &fields,
+                           location loc = location ());
+
     param new_param (type type_,
 		     const std::string &name,
 		     location loc = location ());
@@ -346,6 +351,16 @@ namespace gccjit
     gcc_jit_struct *get_inner_struct () const;
   };
 
+  class union_ : public type
+  {
+  public:
+    union_ ();
+    union_ (gcc_jit_type *inner);
+
+    gcc_jit_type *get_inner_union () const;
+  };
+
+
   class function : public object
   {
   public:
@@ -773,6 +788,26 @@ context::new_opaque_struct_type (const std::string &name,
 		    name.c_str ()));
 }
 
+inline union_
+context::new_union_type (const std::string &name,
+			  std::vector<field> &fields,
+			  location loc)
+{
+  /* Treat std::vector as an array, relying on it not being resized: */
+  field *as_array_of_wrappers = &fields[0];
+
+  /* Treat the array as being of the underlying pointers, relying on
+     the wrapper type being such a pointer internally.	*/
+  gcc_jit_field **as_array_of_ptrs =
+    reinterpret_cast<gcc_jit_field **> (as_array_of_wrappers);
+
+  return union_ (gcc_jit_context_new_union_type (m_inner_ctxt,
+                                                 loc.get_inner_location (),
+                                                 name.c_str (),
+                                                 fields.size (),
+                                                 as_array_of_ptrs));
+}
+
 inline param
 context::new_param (type type_,
 		    const std::string &name,
@@ -1317,6 +1352,13 @@ struct_::get_inner_struct () const
   return reinterpret_cast<gcc_jit_struct *> (get_inner_object ());
 }
 
+// class union_
+inline union_::union_ () : type (NULL) {}
+inline union_::union_ (gcc_jit_type *inner) :
+  type (inner)
+{
+}
+
 // class function
 inline function::function () : object () {}
 inline function::function (gcc_jit_function *inner)

[-- Attachment #4: operator-call.patch --]
[-- Type: text/x-patch, Size: 1783 bytes --]

diff --git a/gcc/jit/libgccjit++.h b/gcc/jit/libgccjit++.h
index 8dc2112367b..27031368890 100644
--- a/gcc/jit/libgccjit++.h
+++ b/gcc/jit/libgccjit++.h
@@ -296,6 +296,11 @@ namespace gccjit
 		     rvalue arg3, rvalue arg4, rvalue arg5,
 		     location loc = location ());
 
+#if __cplusplus >= 201100L
+    template<typename... Args>
+    rvalue new_call(function func, Args... args, location loc = location ());
+#endif
+
     rvalue new_cast (rvalue expr,
 		     type type_,
 		     location loc = location ());
@@ -376,6 +381,11 @@ namespace gccjit
 		       location loc = location ());
     rvalue operator() (rvalue arg0, rvalue arg1, rvalue arg2,
 		       location loc = location ());
+
+#if __cplusplus >= 201100L
+    template<typename... Args>
+    rvalue operator() (Args..., location loc = location ());
+#endif
   };
 
   class block : public object
@@ -1175,6 +1185,18 @@ context::new_call (function func,
   return new_call (func, args, loc);
 }
 
+#if __cplusplus >= 201100L
+template<typename... Args>
+inline rvalue
+context::new_call (function func,
+                   Args... args,
+                   location loc)
+{
+  std::vector<rvalue> vector_args = {args...};
+  return new_call (func, vector_args, loc);
+}
+#endif
+
 inline rvalue
 context::new_cast (rvalue expr,
 		   type type_,
@@ -1552,6 +1574,17 @@ function::operator() (rvalue arg0, rvalue arg1, rvalue arg2,
 				  loc);
 }
 
+#if __cplusplus >= 201100L
+template<typename... Args>
+inline rvalue
+function::operator() (Args... args, location loc)
+{
+  return get_context ().new_call (*this,
+                                  args...,
+                                  loc);
+}
+#endif
+
 // class block
 inline block::block () : object () {}
 inline block::block (gcc_jit_block *inner)

[-- Attachment #5: set_fields.patch --]
[-- Type: text/x-patch, Size: 1115 bytes --]

diff --git a/gcc/jit/libgccjit++.h b/gcc/jit/libgccjit++.h
index 8dc2112367b..14d685c4fa7 100644
--- a/gcc/jit/libgccjit++.h
+++ b/gcc/jit/libgccjit++.h
@@ -344,6 +344,8 @@ namespace gccjit
     struct_ (gcc_jit_struct *inner);
 
     gcc_jit_struct *get_inner_struct () const;
+
+    void set_fields(std::vector<field> &fields, location loc = location ());
   };
 
   class function : public object
@@ -1317,6 +1319,18 @@ struct_::get_inner_struct () const
   return reinterpret_cast<gcc_jit_struct *> (get_inner_object ());
 }
 
+inline void
+struct_::set_fields (std::vector<field> &fields, location loc)
+{
+  field *as_array_of_wrappers = fields.data();
+  gcc_jit_field **as_array_of_ptrs =
+      reinterpret_cast<gcc_jit_field**> (as_array_of_wrappers);
+  return gcc_jit_struct_set_fields (get_inner_struct (),
+                                    loc.get_inner_location (),
+                                    fields.size (),
+                                    as_array_of_ptrs);
+}
+
 // class function
 inline function::function () : object () {}
 inline function::function (gcc_jit_function *inner)

             reply	other threads:[~2017-03-29 21:11 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-01-01  0:00 Joseph Jevnik [this message]
2017-01-01  0:00 ` David Malcolm
2017-01-01  0:00   ` Joseph Jevnik

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAHGq92XQ2_jZYodi=UoW0nUTPmduq-A9H5uRcj5GdtCQwoonhQ@mail.gmail.com' \
    --to=joejev@gmail.com \
    --cc=jit@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).