Committed to branch dmalcolm/jit: New API type: - gcc_jit_struct
New API entrypoints: - gcc_jit_context_new_opaque_struct - gcc_jit_struct_as_type - gcc_jit_struct_set_fields - gcc_jit_context_null: get the NULL value for a pointer type. Changed API entrypoint: - gcc_jit_context_new_struct_type: changed return type from (gcc_jit_type *) to (gcc_jit_struct *). Internally, split out populating the fields of a struct from the creation of said struct. Also, require conditionals to be of boolean type (so that conversions must, for now, be explicit), since the implicit behavior of passing in a pointer didn't match that of C. gcc/jit/ * libgccjit.h (gcc_jit_struct): New. (gcc_jit_context_new_struct_type): Change return type from gcc_jit_type to gcc_jit_struct. (gcc_jit_context_new_opaque_struct): New. (gcc_jit_struct_as_type): New. (gcc_jit_struct_set_fields): New. (gcc_jit_context_null): New. * libgccjit.map (gcc_jit_context_new_opaque_struct): New. (gcc_jit_context_null): New. (gcc_jit_struct_as_type): New. (gcc_jit_struct_set_fields): New. * libgccjit++.h (gccjit::context::new_struct_type): Return a struct_ rather than a type. (gccjit::context::new_opaque_struct_type): New. (gccjit::struct_): New subclass of type. * libgccjit.c (gcc_jit_struct): New. (RETURN_VAL_IF_FAIL_PRINTF1): New. (RETURN_VAL_IF_FAIL_PRINTF2): New. (RETURN_NULL_IF_FAIL_PRINTF1): New. (RETURN_IF_FAIL_PRINTF1): New. (RETURN_IF_FAIL_PRINTF2): New. (gcc_jit_context_new_struct_type): Return a gcc_jit_struct rather than a gcc_jit_type; implement by creating the struct, then setting the fields in it. (gcc_jit_context_new_opaque_struct): New. (gcc_jit_struct_as_type): New. (gcc_jit_struct_set_fields): New. (gcc_jit_context_null): New. (gcc_jit_lvalue_access_field): Use the struct's context when reporting on a NULL field; verify that the field has been placed in a struct. (gcc_jit_rvalue_access_field): Likewise. (is_bool): New. (gcc_jit_function_add_conditional): Use the function's context when reporting errors; verify that boolval's type is indeed boolean. (gcc_jit_function_new_loop): Likewise. * internal-api.h (gcc::jit::recording::context::new_struct_type): Don't accept fields, and return a struct_ rather than a type_, so that fields can be set later. (gcc::jit::recording::struct_::struct_): Store a (fields *) rather than a vec of fields. (gcc::jit::recording::struct_::as_type): New. (gcc::jit::recording::struct_::get_fields): New. (gcc::jit::recording::struct_::set_fields): New. (gcc::jit::recording::struct_::playback_struct): New. (gcc::jit::recording::fields): New class. (gcc::jit::playback::context::new_struct_type): Don't accept fields, and return a struct_ rather than a type_, so that fields can be set later. (gcc::jit::playback::struct_): New subclass of type. * internal-api.c (gcc::jit::recording::context::get_type): With nested contexts, create basic types within the ultimate parent context, allowing for a fast check for the boolean type using pointer equality. (gcc::jit::recording::context::new_struct_type): Don't accept fields, and return a struct_ rather than a type_, so that fields can be set later. (gcc::jit::recording::context::get_opaque_FILE_type): Update for struct-creation changes. (gcc::jit::recording::struct_::struct_): Store a (fields *) rather than a vec of fields. (gcc::jit::recording::struct_::set_fields): New. (gcc::jit::recording::struct_::replay_into): Don't playback the fields, as this is now done by a fields instance. (gcc::jit::recording::fields::fields): New. (gcc::jit::recording::fields::replay_into): New. (gcc::jit::recording::fields::make_debug_string): New. (gcc::jit:: playback::context::new_struct_type): Don't accept fields, and return a struct_ rather than a type_, so that fields can be set later. (gcc::jit::playback::struct_::set_fields): New. * TODO.rst: Update. gcc/testsuite/ * jit.dg/test-accessing-struct.c (create_code): Update for change to return type of gcc_jit_context_new_struct_type. * jit.dg/test-arrays.c (create_code): Likewise. * jit.dg/test-error-accessing-field-in-other-struct.c (create_code): Likewise. * jit.dg/test-error-dereference-field-of-non-pointer.c (create_code): Likewise. * jit.dg/test-fuzzer.c (make_random_type): Likewise. * jit.dg/test-nested-contexts.c (make_types): Likewise. * jit.dg/test-quadratic.c (make_types): Likewise. * jit.dg/test-reading-struct.c (create_code): Likewise. * jit.dg/test-types.c (create_code): Likewise. * jit.dg/test-linked-list.c: New selftest, exercising gcc_jit_context_new_opaque_struct, gcc_jit_type_get_pointer, and gcc_jit_context_null. * jit.dg/test-combination.c: Add test-linked-list.c --- gcc/jit/ChangeLog.jit | 82 ++++++++++++ gcc/jit/TODO.rst | 24 +--- gcc/jit/internal-api.c | 120 +++++++++++------ gcc/jit/internal-api.h | 61 +++++++-- gcc/jit/libgccjit++.h | 55 ++++++-- gcc/jit/libgccjit.c | 143 +++++++++++++++++++-- gcc/jit/libgccjit.h | 27 +++- gcc/jit/libgccjit.map | 4 + gcc/testsuite/ChangeLog.jit | 20 +++ gcc/testsuite/jit.dg/test-accessing-struct.c | 5 +- gcc/testsuite/jit.dg/test-arrays.c | 4 +- gcc/testsuite/jit.dg/test-combination.c | 9 ++ .../test-error-accessing-field-in-other-struct.c | 7 +- .../test-error-dereference-field-of-non-pointer.c | 6 +- gcc/testsuite/jit.dg/test-fuzzer.c | 4 +- gcc/testsuite/jit.dg/test-linked-list.c | 133 +++++++++++++++++++ gcc/testsuite/jit.dg/test-nested-contexts.c | 5 +- gcc/testsuite/jit.dg/test-quadratic.c | 5 +- gcc/testsuite/jit.dg/test-reading-struct.c | 3 +- gcc/testsuite/jit.dg/test-types.c | 13 +- 20 files changed, 617 insertions(+), 113 deletions(-) create mode 100644 gcc/testsuite/jit.dg/test-linked-list.c diff --git a/gcc/jit/ChangeLog.jit b/gcc/jit/ChangeLog.jit index b0e12b1..860bee6 100644 --- a/gcc/jit/ChangeLog.jit +++ b/gcc/jit/ChangeLog.jit @@ -1,5 +1,87 @@ 2014-02-18 David Malcolm <dmalc...@redhat.com> + * libgccjit.h (gcc_jit_struct): New. + (gcc_jit_context_new_struct_type): Change return type from gcc_jit_type + to gcc_jit_struct. + (gcc_jit_context_new_opaque_struct): New. + (gcc_jit_struct_as_type): New. + (gcc_jit_struct_set_fields): New. + (gcc_jit_context_null): New. + + * libgccjit.map (gcc_jit_context_new_opaque_struct): New. + (gcc_jit_context_null): New. + (gcc_jit_struct_as_type): New. + (gcc_jit_struct_set_fields): New. + + * libgccjit++.h (gccjit::context::new_struct_type): Return a + struct_ rather than a type. + (gccjit::context::new_opaque_struct_type): New. + (gccjit::struct_): New subclass of type. + + * libgccjit.c (gcc_jit_struct): New. + (RETURN_VAL_IF_FAIL_PRINTF1): New. + (RETURN_VAL_IF_FAIL_PRINTF2): New. + (RETURN_NULL_IF_FAIL_PRINTF1): New. + (RETURN_IF_FAIL_PRINTF1): New. + (RETURN_IF_FAIL_PRINTF2): New. + (gcc_jit_context_new_struct_type): Return a gcc_jit_struct rather + than a gcc_jit_type; implement by creating the struct, then + setting the fields in it. + (gcc_jit_context_new_opaque_struct): New. + (gcc_jit_struct_as_type): New. + (gcc_jit_struct_set_fields): New. + (gcc_jit_context_null): New. + (gcc_jit_lvalue_access_field): Use the struct's context when + reporting on a NULL field; verify that the field has been placed + in a struct. + (gcc_jit_rvalue_access_field): Likewise. + (is_bool): New. + (gcc_jit_function_add_conditional): Use the function's context + when reporting errors; verify that boolval's type is indeed + boolean. + (gcc_jit_function_new_loop): Likewise. + + * internal-api.h (gcc::jit::recording::context::new_struct_type): + Don't accept fields, and return a struct_ rather than a type_, so + that fields can be set later. + (gcc::jit::recording::struct_::struct_): Store a (fields *) rather + than a vec of fields. + (gcc::jit::recording::struct_::as_type): New. + (gcc::jit::recording::struct_::get_fields): New. + (gcc::jit::recording::struct_::set_fields): New. + (gcc::jit::recording::struct_::playback_struct): New. + (gcc::jit::recording::fields): New class. + (gcc::jit::playback::context::new_struct_type): Don't accept + fields, and return a struct_ rather than a type_, so that fields + can be set later. + (gcc::jit::playback::struct_): New subclass of type. + + * internal-api.c (gcc::jit::recording::context::get_type): With + nested contexts, create basic types within the ultimate parent + context, allowing for a fast check for the boolean type using + pointer equality. + (gcc::jit::recording::context::new_struct_type): Don't accept + fields, and return a struct_ rather than a type_, so that fields + can be set later. + (gcc::jit::recording::context::get_opaque_FILE_type): Update for + struct-creation changes. + (gcc::jit::recording::struct_::struct_): Store a (fields *) rather + than a vec of fields. + (gcc::jit::recording::struct_::set_fields): New. + (gcc::jit::recording::struct_::replay_into): Don't playback the + fields, as this is now done by a fields instance. + (gcc::jit::recording::fields::fields): New. + (gcc::jit::recording::fields::replay_into): New. + (gcc::jit::recording::fields::make_debug_string): New. + (gcc::jit:: playback::context::new_struct_type): Don't accept + fields, and return a struct_ rather than a type_, so that fields + can be set later. + (gcc::jit::playback::struct_::set_fields): New. + + * TODO.rst: Update. + +2014-02-18 David Malcolm <dmalc...@redhat.com> + * libgccjit.c (gcc_jit_function_new_local): Use the context of the function when reporting errors. (gcc_jit_function_place_forward_label): Likewise. diff --git a/gcc/jit/TODO.rst b/gcc/jit/TODO.rst index c149dde..7288aef 100644 --- a/gcc/jit/TODO.rst +++ b/gcc/jit/TODO.rst @@ -18,23 +18,6 @@ Initial Release * more types: * unions * function ptrs - * explicitly opaque structs, perhaps: - - extern gcc_jit_type * - gcc_jit_context_new_opaque_struct (gcc_jit_context *ctxt, - const char *name); - - * ability to create self-referential structs, or cycles in the graph: - - struct foo { struct bar *m_bar; } - struct bar { struct foo *m_foo; } - - * get int type with given number of either bits or bytes: - - extern gcc_jit_type * - gcc_jit_context_get_int_type (gcc_jit_context *ctxt, - int num_bytes, - int is_signed); * ability to bind a pre-existing global variable @@ -109,13 +92,12 @@ Initial Release * gcc_jit_context_new_rvalue_from_int: must be a numeric type - * gcc_jit_context_zero: must be a numeric type. If we do this should - we introduce a gcc_jit_context_null for pointer types? (you can do - this via gcc_jit_context_new_rvalue_from_ptr, but having an explicit - hook is friendlier). + * gcc_jit_context_zero: must be a numeric type * gcc_jit_context_one: must be a numeric type + * gcc_jit_context_null: must be a pointer type + * gcc_jit_context_new_rvalue_from_double: must be a numeric type * gcc_jit_context_new_rvalue_from_ptr: must be a pointer type diff --git a/gcc/jit/internal-api.c b/gcc/jit/internal-api.c index dacb55d..37fe70b 100644 --- a/gcc/jit/internal-api.c +++ b/gcc/jit/internal-api.c @@ -211,9 +211,15 @@ recording::context::get_type (enum gcc_jit_types kind) give the same object. */ if (!m_basic_types[kind]) { - recording::type *result = new memento_of_get_type (this, kind); - record (result); - m_basic_types[kind] = result; + /* For basic types, use them from the parent ctxt. */ + if (m_parent_ctxt) + m_basic_types[kind] = m_parent_ctxt->get_type (kind); + else + { + recording::type *result = new memento_of_get_type (this, kind); + record (result); + m_basic_types[kind] = result; + } } return m_basic_types[kind]; @@ -278,18 +284,11 @@ recording::context::new_field (recording::location *loc, return result; } -recording::type * +recording::struct_ * recording::context::new_struct_type (recording::location *loc, - const char *name, - int num_fields, - field **fields) + const char *name) { - vec<field *> vec_fields; - vec_fields.create (num_fields); - for (int i = 0; i < num_fields; i++) - vec_fields.safe_push (fields[i]); - recording::type *result = new struct_ (this, loc, new_string (name), - vec_fields); + recording::struct_ *result = new struct_ (this, loc, new_string (name)); record (result); return result; } @@ -545,7 +544,7 @@ recording::type * recording::context::get_opaque_FILE_type () { if (!m_FILE_type) - m_FILE_type = new_struct_type (NULL, "FILE", 0, NULL); + m_FILE_type = new_struct_type (NULL, "FILE"); return m_FILE_type; } @@ -918,19 +917,24 @@ recording::field::make_debug_string () /* gcc::jit::recording::struct_:: */ recording::struct_::struct_ (context *ctxt, location *loc, - string *name, - vec<field *> fields) + string *name) : type (ctxt), m_loc (loc), m_name (name), - m_fields (fields) + m_fields (NULL) { - /* Mark all fields as belonging to the new struct: */ - for (unsigned i = 0; i < fields.length (); i++) - { - gcc_assert (m_fields[i]->get_container () == NULL); - m_fields[i]->set_container (this); - } +} + +void +recording::struct_::set_fields (location *loc, + int num_fields, + field **field_array) +{ + m_loc = loc; + gcc_assert (NULL == m_fields); + + m_fields = new fields (this, num_fields, field_array); + m_ctxt->record (m_fields); } recording::type * @@ -942,15 +946,9 @@ recording::struct_::dereference () void recording::struct_::replay_into (replayer *r) { - vec<playback::field *> playback_fields; - playback_fields.create (m_fields.length ()); - for (unsigned i = 0; i < m_fields.length (); i++) - playback_fields.safe_push (m_fields[i]->playback_field ()); - set_playback_obj ( r->new_struct_type (playback_location (m_loc), - m_name->c_str (), - &playback_fields)); + m_name->c_str ())); } recording::string * @@ -960,6 +958,39 @@ recording::struct_::make_debug_string () "struct %s", m_name->c_str ()); } +/* gcc::jit::recording::fields:: */ +recording::fields::fields (struct_ *struct_, + int num_fields, + field **fields) +: memento (struct_->m_ctxt), + m_struct (struct_), + m_fields () +{ + for (int i = 0; i < num_fields; i++) + { + gcc_assert (fields[i]->get_container () == NULL); + fields[i]->set_container (m_struct); + m_fields.safe_push (fields[i]); + } +} + +void +recording::fields::replay_into (replayer *) +{ + vec<playback::field *> playback_fields; + playback_fields.create (m_fields.length ()); + for (unsigned i = 0; i < m_fields.length (); i++) + playback_fields.safe_push (m_fields[i]->playback_field ()); + m_struct->playback_struct ()->set_fields (playback_fields); +} + +recording::string * +recording::fields::make_debug_string () +{ + return string::from_printf (m_ctxt, + "fields"); +} + /* gcc::jit::recording::rvalue:: */ recording::rvalue * @@ -1937,25 +1968,35 @@ new_field (location *loc, return new field (decl); } -playback::type * +playback::struct_ * playback::context:: new_struct_type (location *loc, - const char *name, - vec<field *> *fields) + const char *name) { gcc_assert (name); - gcc_assert (fields); - /* Compare with c/c-decl.c: start_struct and finish_struct. */ + /* Compare with c/c-decl.c: start_struct. */ tree t = make_node (RECORD_TYPE); TYPE_NAME (t) = get_identifier (name); TYPE_SIZE (t) = 0; + if (loc) + set_tree_location (t, loc); + + return new struct_ (t); +} + +void +playback::struct_::set_fields (const vec<playback::field *> &fields) +{ + /* Compare with c/c-decl.c: finish_struct. */ + tree t = as_tree (); + tree fieldlist = NULL; - for (unsigned i = 0; i < fields->length (); i++) + for (unsigned i = 0; i < fields.length (); i++) { - field *f = (*fields)[i]; + field *f = fields[i]; DECL_CONTEXT (f->as_tree ()) = t; fieldlist = chainon (f->as_tree (), fieldlist); } @@ -1963,11 +2004,6 @@ new_struct_type (location *loc, TYPE_FIELDS (t) = fieldlist; layout_type (t); - - if (loc) - set_tree_location (t, loc); - - return new type (t); } playback::type * diff --git a/gcc/jit/internal-api.h b/gcc/jit/internal-api.h index 45ab9ea..1be192e 100644 --- a/gcc/jit/internal-api.h +++ b/gcc/jit/internal-api.h @@ -85,6 +85,7 @@ namespace recording { class function_type; class field; class struct_; + class fields; class function; class label; class rvalue; @@ -98,6 +99,7 @@ namespace playback { class location; class type; class field; + class struct_; class function; class label; class rvalue; @@ -160,12 +162,9 @@ public: type *type, const char *name); - type * + struct_ * new_struct_type (location *loc, - const char *name, - int num_fields, - field **fields); - + const char *name); param * new_param (location *loc, @@ -619,19 +618,52 @@ class struct_ : public type public: struct_ (context *ctxt, location *loc, - string *name, - vec<field *> fields); + string *name); + + type * + as_type () { return this; } + + fields * get_fields () { return m_fields; } + + void + set_fields (location *loc, + int num_fields, + field **fields); type *dereference (); void replay_into (replayer *r); + playback::struct_ * + playback_struct () + { + return static_cast <playback::struct_ *> (m_playback_obj); + } + private: string * make_debug_string (); private: location *m_loc; string *m_name; + fields *m_fields; +}; + +// memento of struct_::set_fields +class fields : public memento +{ +public: + fields (struct_ *struct_, + int num_fields, + field **fields); + + void replay_into (replayer *r); + +private: + string * make_debug_string (); + +private: + struct_ *m_struct; vec<field *> m_fields; }; @@ -1481,10 +1513,9 @@ public: type *type, const char *name); - type * + struct_ * new_struct_type (location *loc, - const char *name, - vec<field *> *fields); + const char *name); type * new_function_type (type *return_type, @@ -1682,6 +1713,16 @@ private: tree m_inner; }; +class struct_ : public type +{ +public: + struct_ (tree inner) + : type (inner) + {} + + void set_fields (const vec<field *> &fields); +}; + class field : public wrapper { public: diff --git a/gcc/jit/libgccjit++.h b/gcc/jit/libgccjit++.h index a718d0c..63f8610 100644 --- a/gcc/jit/libgccjit++.h +++ b/gcc/jit/libgccjit++.h @@ -19,6 +19,7 @@ namespace gccjit class location; class field; class type; + class struct_; class param; class function; class label; @@ -97,9 +98,12 @@ namespace gccjit field new_field (type type_, const std::string &name, location loc = location ()); - type new_struct_type (const std::string &name, - std::vector<field> &fields, - location loc = location ()); + struct_ new_struct_type (const std::string &name, + std::vector<field> &fields, + location loc = location ()); + + struct_ new_opaque_struct_type (const std::string &name, + location loc = location ()); param new_param (type type_, const std::string &name, @@ -264,6 +268,15 @@ namespace gccjit rvalue one (); }; + class struct_ : public type + { + public: + struct_ (); + struct_ (gcc_jit_struct *inner); + + gcc_jit_struct *get_inner_struct () const; + }; + class function : public object { public: @@ -525,7 +538,7 @@ context::new_field (type type_, const std::string &name, location loc) name.c_str ())); } -inline type +inline struct_ context::new_struct_type (const std::string &name, std::vector<field> &fields, location loc) @@ -538,11 +551,21 @@ context::new_struct_type (const std::string &name, gcc_jit_field **as_array_of_ptrs = reinterpret_cast<gcc_jit_field **> (as_array_of_wrappers); - return type (gcc_jit_context_new_struct_type (m_inner_ctxt, - loc.get_inner_location (), - name.c_str (), - fields.size (), - as_array_of_ptrs)); + return struct_ (gcc_jit_context_new_struct_type (m_inner_ctxt, + loc.get_inner_location (), + name.c_str (), + fields.size (), + as_array_of_ptrs)); +} + +inline struct_ +context::new_opaque_struct_type (const std::string &name, + location loc) +{ + return struct_ (gcc_jit_context_new_opaque_struct ( + m_inner_ctxt, + loc.get_inner_location (), + name.c_str ())); } inline param @@ -1020,6 +1043,20 @@ type::one () return get_context ().new_rvalue (*this, 1); } +// class struct_ +inline struct_::struct_ () : type (NULL) {} +inline struct_::struct_ (gcc_jit_struct *inner) : + type (gcc_jit_struct_as_type (inner)) +{ +} + +inline gcc_jit_struct * +struct_::get_inner_struct () const +{ + /* Manual downcast: */ + return reinterpret_cast<gcc_jit_struct *> (get_inner_object ()); +} + // class function inline function::function () : object (NULL) {} inline function::function (gcc_jit_function *inner) diff --git a/gcc/jit/libgccjit.c b/gcc/jit/libgccjit.c index b5b3968..d089ad5 100644 --- a/gcc/jit/libgccjit.c +++ b/gcc/jit/libgccjit.c @@ -44,6 +44,10 @@ struct gcc_jit_type : public gcc::jit::recording::type { }; +struct gcc_jit_struct : public gcc::jit::recording::struct_ +{ +}; + struct gcc_jit_field : public gcc::jit::recording::field { }; @@ -93,6 +97,16 @@ struct gcc_jit_loop : public gcc::jit::recording::loop } \ JIT_END_STMT +#define RETURN_VAL_IF_FAIL_PRINTF1(TEST_EXPR, RETURN_EXPR, CTXT, ERR_FMT, A0) \ + JIT_BEGIN_STMT \ + if (!(TEST_EXPR)) \ + { \ + jit_error ((CTXT), "%s: " ERR_FMT, \ + __func__, (A0)); \ + return (RETURN_EXPR); \ + } \ + JIT_END_STMT + #define RETURN_VAL_IF_FAIL_PRINTF2(TEST_EXPR, RETURN_EXPR, CTXT, ERR_FMT, A0, A1) \ JIT_BEGIN_STMT \ if (!(TEST_EXPR)) \ @@ -136,6 +150,9 @@ struct gcc_jit_loop : public gcc::jit::recording::loop #define RETURN_NULL_IF_FAIL(TEST_EXPR, CTXT, ERR_MSG) \ RETURN_VAL_IF_FAIL ((TEST_EXPR), NULL, (CTXT), (ERR_MSG)) +#define RETURN_NULL_IF_FAIL_PRINTF1(TEST_EXPR, CTXT, ERR_FMT, A0) \ + RETURN_VAL_IF_FAIL_PRINTF1 (TEST_EXPR, NULL, CTXT, ERR_FMT, A0) + #define RETURN_NULL_IF_FAIL_PRINTF2(TEST_EXPR, CTXT, ERR_FMT, A0, A1) \ RETURN_VAL_IF_FAIL_PRINTF2 (TEST_EXPR, NULL, CTXT, ERR_FMT, A0, A1) @@ -157,6 +174,26 @@ struct gcc_jit_loop : public gcc::jit::recording::loop } \ JIT_END_STMT +#define RETURN_IF_FAIL_PRINTF1(TEST_EXPR, CTXT, ERR_FMT, A0) \ + JIT_BEGIN_STMT \ + if (!(TEST_EXPR)) \ + { \ + jit_error ((CTXT), "%s: " ERR_FMT, \ + __func__, (A0)); \ + return; \ + } \ + JIT_END_STMT + +#define RETURN_IF_FAIL_PRINTF2(TEST_EXPR, CTXT, ERR_FMT, A0, A1) \ + JIT_BEGIN_STMT \ + if (!(TEST_EXPR)) \ + { \ + jit_error ((CTXT), "%s: " ERR_FMT, \ + __func__, (A0), (A1)); \ + return; \ + } \ + JIT_END_STMT + #define RETURN_IF_FAIL_PRINTF4(TEST_EXPR, CTXT, ERR_FMT, A0, A1, A2, A3) \ JIT_BEGIN_STMT \ if (!(TEST_EXPR)) \ @@ -330,7 +367,7 @@ gcc_jit_field_as_object (gcc_jit_field *field) return static_cast <gcc_jit_object *> (field->as_object ()); } -gcc_jit_type * +gcc_jit_struct * gcc_jit_context_new_struct_type (gcc_jit_context *ctxt, gcc_jit_location *loc, const char *name, @@ -352,10 +389,61 @@ gcc_jit_context_new_struct_type (gcc_jit_context *ctxt, fields[i]->get_container ()->get_debug_string ()); } - return (gcc_jit_type *)ctxt->new_struct_type (loc, name, num_fields, - (gcc::jit::recording::field **)fields); + gcc::jit::recording::struct_ *result = + ctxt->new_struct_type (loc, name); + result->set_fields (loc, + num_fields, + (gcc::jit::recording::field **)fields); + return static_cast<gcc_jit_struct *> (result); +} + +gcc_jit_struct * +gcc_jit_context_new_opaque_struct (gcc_jit_context *ctxt, + gcc_jit_location *loc, + const char *name) +{ + RETURN_NULL_IF_FAIL (ctxt, NULL, "NULL context"); + RETURN_NULL_IF_FAIL (name, ctxt, "NULL name"); + + return (gcc_jit_struct *)ctxt->new_struct_type (loc, name); } +gcc_jit_type * +gcc_jit_struct_as_type (gcc_jit_struct *struct_type) +{ + RETURN_NULL_IF_FAIL (struct_type, NULL, "NULL struct_type"); + + return static_cast <gcc_jit_type *> (struct_type->as_type ()); +} + +void +gcc_jit_struct_set_fields (gcc_jit_struct *struct_type, + gcc_jit_location *loc, + int num_fields, + gcc_jit_field **fields) +{ + RETURN_IF_FAIL (struct_type, NULL, "NULL struct_type"); + gcc::jit::recording::context *ctxt = struct_type->m_ctxt; + RETURN_IF_FAIL_PRINTF1 ( + NULL == struct_type->get_fields (), ctxt, + "%s already has had fields set", + struct_type->get_debug_string ()); + if (num_fields) + RETURN_IF_FAIL (fields, ctxt, "NULL fields ptr"); + for (int i = 0; i < num_fields; i++) + { + RETURN_IF_FAIL (fields[i], ctxt, "NULL field ptr"); + RETURN_IF_FAIL_PRINTF2 ( + NULL == fields[i]->get_container (), + ctxt, + "%s is already a field of %s", + fields[i]->get_debug_string (), + fields[i]->get_container ()->get_debug_string ()); + } + + struct_type->set_fields (loc, num_fields, + (gcc::jit::recording::field **)fields); +} /* Constructing functions. */ gcc_jit_param * @@ -597,6 +685,16 @@ gcc_jit_context_new_rvalue_from_ptr (gcc_jit_context *ctxt, } gcc_jit_rvalue * +gcc_jit_context_null (gcc_jit_context *ctxt, + gcc_jit_type *pointer_type) +{ + RETURN_NULL_IF_FAIL (ctxt, NULL, "NULL context"); + RETURN_NULL_IF_FAIL (pointer_type, ctxt, "NULL type"); + + return gcc_jit_context_new_rvalue_from_ptr (ctxt, pointer_type, NULL); +} + +gcc_jit_rvalue * gcc_jit_context_new_string_literal (gcc_jit_context *ctxt, const char *value) { @@ -751,7 +849,11 @@ gcc_jit_lvalue_access_field (gcc_jit_lvalue *struct_, gcc_jit_field *field) { RETURN_NULL_IF_FAIL (struct_, NULL, "NULL struct"); - RETURN_NULL_IF_FAIL (field, NULL, "NULL field"); + gcc::jit::recording::context *ctxt = struct_->m_ctxt; + RETURN_NULL_IF_FAIL (field, ctxt, "NULL field"); + RETURN_NULL_IF_FAIL_PRINTF1 (field->get_container (), field->m_ctxt, + "field %s has not been placed in a struct", + field->get_debug_string ()); return (gcc_jit_lvalue *)struct_->access_field (loc, field); } @@ -762,7 +864,11 @@ gcc_jit_rvalue_access_field (gcc_jit_rvalue *struct_, gcc_jit_field *field) { RETURN_NULL_IF_FAIL (struct_, NULL, "NULL struct"); - RETURN_NULL_IF_FAIL (field, NULL, "NULL field"); + gcc::jit::recording::context *ctxt = struct_->m_ctxt; + RETURN_NULL_IF_FAIL (field, ctxt, "NULL field"); + RETURN_NULL_IF_FAIL_PRINTF1 (field->get_container (), field->m_ctxt, + "field %s has not been placed in a struct", + field->get_debug_string ()); return (gcc_jit_rvalue *)struct_->access_field (loc, field); } @@ -912,6 +1018,15 @@ gcc_jit_function_add_assignment_op (gcc_jit_function *func, return func->add_assignment_op (loc, lvalue, op, rvalue); } +static bool +is_bool (gcc_jit_rvalue *boolval) +{ + gcc::jit::recording::type *actual_type = boolval->get_type (); + gcc::jit::recording::type *bool_type = + boolval->m_ctxt->get_type (GCC_JIT_TYPE_BOOL); + return actual_type == bool_type; +} + void gcc_jit_function_add_conditional (gcc_jit_function *func, gcc_jit_location *loc, @@ -920,8 +1035,14 @@ gcc_jit_function_add_conditional (gcc_jit_function *func, gcc_jit_label *on_false) { RETURN_IF_NOT_FUNC_DEFINITION (func); - RETURN_IF_FAIL (boolval, NULL, "NULL boolval"); - RETURN_IF_FAIL (on_true, NULL, "NULL on_true"); + gcc::jit::recording::context *ctxt = func->m_ctxt; + RETURN_IF_FAIL (boolval, ctxt, "NULL boolval"); + RETURN_IF_FAIL_PRINTF2 ( + is_bool (boolval), ctxt, + "%s (type: %s) is not of boolean type ", + boolval->get_debug_string (), + boolval->get_type ()->get_debug_string ()); + RETURN_IF_FAIL (on_true, ctxt, "NULL on_true"); /* on_false can be NULL */ return func->add_conditional (loc, boolval, on_true, on_false); @@ -980,7 +1101,13 @@ gcc_jit_function_new_loop (gcc_jit_function *func, gcc_jit_rvalue *boolval) { RETURN_NULL_IF_NOT_FUNC_DEFINITION (func); - RETURN_NULL_IF_FAIL (boolval, NULL, "NULL boolval"); + gcc::jit::recording::context *ctxt = func->m_ctxt; + RETURN_NULL_IF_FAIL (boolval, ctxt, "NULL boolval"); + RETURN_NULL_IF_FAIL_PRINTF2 ( + is_bool (boolval), ctxt, + "%s (type: %s) is not of boolean type ", + boolval->get_debug_string (), + boolval->get_type ()->get_debug_string ()); return (gcc_jit_loop *)func->new_loop (loc, boolval, NULL, NULL); } diff --git a/gcc/jit/libgccjit.h b/gcc/jit/libgccjit.h index 3751bdd..3ea6653 100644 --- a/gcc/jit/libgccjit.h +++ b/gcc/jit/libgccjit.h @@ -36,6 +36,7 @@ typedef struct gcc_jit_result gcc_jit_result; +- gcc_jit_object +- gcc_jit_location +- gcc_jit_type + +- gcc_jit_struct +- gcc_jit_field +- gcc_jit_function +- gcc_jit_label @@ -67,6 +68,10 @@ typedef struct gcc_jit_type gcc_jit_type; Fields cannot be shared between structs. */ typedef struct gcc_jit_field gcc_jit_field; +/* A gcc_jit_struct encapsulates a struct type, either one that we have + the layout for, or an opaque type. */ +typedef struct gcc_jit_struct gcc_jit_struct; + /* A gcc_jit_function encapsulates a function: either one that you're creating yourself, or a reference to one that you're dynamically linking to within the rest of the process. */ @@ -385,13 +390,29 @@ gcc_jit_context_new_field (gcc_jit_context *ctxt, extern gcc_jit_object * gcc_jit_field_as_object (gcc_jit_field *field); -extern gcc_jit_type * +extern gcc_jit_struct * gcc_jit_context_new_struct_type (gcc_jit_context *ctxt, gcc_jit_location *loc, const char *name, int num_fields, gcc_jit_field **fields); +extern gcc_jit_struct * +gcc_jit_context_new_opaque_struct (gcc_jit_context *ctxt, + gcc_jit_location *loc, + const char *name); + +extern gcc_jit_type * +gcc_jit_struct_as_type (gcc_jit_struct *struct_type); + +/* Populating the fields of a formerly-opaque struct type. + This can only be called once on a given struct type. */ +extern void +gcc_jit_struct_set_fields (gcc_jit_struct *struct_type, + gcc_jit_location *loc, + int num_fields, + gcc_jit_field **fields); + /********************************************************************** Constructing functions. **********************************************************************/ @@ -511,6 +532,10 @@ gcc_jit_context_new_rvalue_from_ptr (gcc_jit_context *ctxt, gcc_jit_type *pointer_type, void *value); +extern gcc_jit_rvalue * +gcc_jit_context_null (gcc_jit_context *ctxt, + gcc_jit_type *pointer_type); + /* String literals. */ extern gcc_jit_rvalue * gcc_jit_context_new_string_literal (gcc_jit_context *ctxt, diff --git a/gcc/jit/libgccjit.map b/gcc/jit/libgccjit.map index 6dde3a1..fbdca38 100644 --- a/gcc/jit/libgccjit.map +++ b/gcc/jit/libgccjit.map @@ -18,6 +18,7 @@ gcc_jit_context_new_function; gcc_jit_context_new_global; gcc_jit_context_new_location; + gcc_jit_context_new_opaque_struct; gcc_jit_context_new_param; gcc_jit_context_new_rvalue_from_double; gcc_jit_context_new_rvalue_from_int; @@ -25,6 +26,7 @@ gcc_jit_context_new_string_literal; gcc_jit_context_new_struct_type; gcc_jit_context_new_unary_op; + gcc_jit_context_null; gcc_jit_context_one; gcc_jit_context_release; gcc_jit_context_set_bool_option; @@ -67,6 +69,8 @@ gcc_jit_rvalue_dereference; gcc_jit_rvalue_dereference_field; gcc_jit_rvalue_get_type; + gcc_jit_struct_as_type; + gcc_jit_struct_set_fields; gcc_jit_type_as_object; gcc_jit_type_get_const; gcc_jit_type_get_pointer; diff --git a/gcc/testsuite/ChangeLog.jit b/gcc/testsuite/ChangeLog.jit index ec1d76a..0299115 100644 --- a/gcc/testsuite/ChangeLog.jit +++ b/gcc/testsuite/ChangeLog.jit @@ -1,3 +1,23 @@ +2014-02-18 David Malcolm <dmalc...@redhat.com> + + * jit.dg/test-accessing-struct.c (create_code): Update for change to + return type of gcc_jit_context_new_struct_type. + * jit.dg/test-arrays.c (create_code): Likewise. + * jit.dg/test-error-accessing-field-in-other-struct.c (create_code): + Likewise. + * jit.dg/test-error-dereference-field-of-non-pointer.c (create_code): + Likewise. + * jit.dg/test-fuzzer.c (make_random_type): Likewise. + * jit.dg/test-nested-contexts.c (make_types): Likewise. + * jit.dg/test-quadratic.c (make_types): Likewise. + * jit.dg/test-reading-struct.c (create_code): Likewise. + * jit.dg/test-types.c (create_code): Likewise. + + * jit.dg/test-linked-list.c: New selftest, exercising + gcc_jit_context_new_opaque_struct, gcc_jit_type_get_pointer, and + gcc_jit_context_null. + * jit.dg/test-combination.c: Add test-linked-list.c + 2014-02-14 David Malcolm <dmalc...@redhat.com> * jit.dg/test-operator-overloading.cc (make_test_quadratic): Use diff --git a/gcc/testsuite/jit.dg/test-accessing-struct.c b/gcc/testsuite/jit.dg/test-accessing-struct.c index b28adeb..eb4ecca 100644 --- a/gcc/testsuite/jit.dg/test-accessing-struct.c +++ b/gcc/testsuite/jit.dg/test-accessing-struct.c @@ -42,9 +42,10 @@ create_code (gcc_jit_context *ctxt, void *user_data) int_type, "z"); gcc_jit_field *fields[] = {x, y, z}; - gcc_jit_type *struct_type = + gcc_jit_struct *struct_type = gcc_jit_context_new_struct_type (ctxt, NULL, "foo", 3, fields); - gcc_jit_type *ptr_type = gcc_jit_type_get_pointer (struct_type); + gcc_jit_type *ptr_type = + gcc_jit_type_get_pointer (gcc_jit_struct_as_type (struct_type)); /* Build the test function. */ gcc_jit_param *param_f = diff --git a/gcc/testsuite/jit.dg/test-arrays.c b/gcc/testsuite/jit.dg/test-arrays.c index 2cff561..12ea77e 100644 --- a/gcc/testsuite/jit.dg/test-arrays.c +++ b/gcc/testsuite/jit.dg/test-arrays.c @@ -53,7 +53,7 @@ create_code (gcc_jit_context *ctxt, void *user_data) field_m_after, }; - gcc_jit_type *struct_type = + gcc_jit_struct *struct_type = gcc_jit_context_new_struct_type ( ctxt, NULL, @@ -61,7 +61,7 @@ create_code (gcc_jit_context *ctxt, void *user_data) 3, fields); gcc_jit_type *struct_ptr_type = - gcc_jit_type_get_pointer (struct_type); + gcc_jit_type_get_pointer (gcc_jit_struct_as_type (struct_type)); /* Build the test_fn. */ gcc_jit_param *param_ah = diff --git a/gcc/testsuite/jit.dg/test-combination.c b/gcc/testsuite/jit.dg/test-combination.c index 7fc07ab..cd8a0f3 100644 --- a/gcc/testsuite/jit.dg/test-combination.c +++ b/gcc/testsuite/jit.dg/test-combination.c @@ -66,6 +66,13 @@ #undef create_code #undef verify_code +/* test-linked-list.c */ +#define create_code create_code_linked_list +#define verify_code verify_code_linked_list +#include "test-linked-list.c" +#undef create_code +#undef verify_code + /* test-quadratic.c */ #define create_code create_code_quadratic #define verify_code verify_code_quadratic @@ -127,6 +134,7 @@ create_code (gcc_jit_context *ctxt, void * user_data) create_code_fibonacci (ctxt, user_data); create_code_functions (ctxt, user_data); create_code_hello_world (ctxt, user_data); + create_code_linked_list (ctxt, user_data); create_code_string_literal (ctxt, user_data); create_code_sum_of_squares (ctxt, user_data); create_code_types (ctxt, user_data); @@ -144,6 +152,7 @@ verify_code (gcc_jit_context *ctxt, gcc_jit_result *result) verify_code_fibonacci (ctxt, result); verify_code_functions (ctxt, result); verify_code_hello_world (ctxt, result); + verify_code_linked_list (ctxt, result); verify_code_string_literal (ctxt, result); verify_code_sum_of_squares (ctxt, result); verify_code_types (ctxt, result); diff --git a/gcc/testsuite/jit.dg/test-error-accessing-field-in-other-struct.c b/gcc/testsuite/jit.dg/test-error-accessing-field-in-other-struct.c index 6789195..1cc2cb6 100644 --- a/gcc/testsuite/jit.dg/test-error-accessing-field-in-other-struct.c +++ b/gcc/testsuite/jit.dg/test-error-accessing-field-in-other-struct.c @@ -45,7 +45,7 @@ create_code (gcc_jit_context *ctxt, void *user_data) int_type, "y"); gcc_jit_field *foo_fields[] = {x, y}; - gcc_jit_type *struct_foo = + gcc_jit_struct *struct_foo = gcc_jit_context_new_struct_type (ctxt, NULL, "foo", 2, foo_fields); /* Map "struct bar". */ @@ -62,11 +62,12 @@ create_code (gcc_jit_context *ctxt, void *user_data) /* We don't actually need a gcc_jit_type for "struct bar" for the test. */ #if 0 gcc_jit_field *bar_fields[] = {p, q}; - gcc_jit_type *struct_bar = + gcc_jit_struct *struct_bar = gcc_jit_context_new_struct_type (ctxt, NULL, "foo", 2, bar_fields); #endif - gcc_jit_type *foo_ptr = gcc_jit_type_get_pointer (struct_foo); + gcc_jit_type *foo_ptr = + gcc_jit_type_get_pointer (gcc_jit_struct_as_type (struct_foo)); /* Build the test function. */ gcc_jit_param *param_f = diff --git a/gcc/testsuite/jit.dg/test-error-dereference-field-of-non-pointer.c b/gcc/testsuite/jit.dg/test-error-dereference-field-of-non-pointer.c index e69ca8d..287498d 100644 --- a/gcc/testsuite/jit.dg/test-error-dereference-field-of-non-pointer.c +++ b/gcc/testsuite/jit.dg/test-error-dereference-field-of-non-pointer.c @@ -40,7 +40,7 @@ create_code (gcc_jit_context *ctxt, void *user_data) int_type, "y"); gcc_jit_field *foo_fields[] = {x, y}; - gcc_jit_type *struct_foo = + gcc_jit_struct *struct_foo = gcc_jit_context_new_struct_type (ctxt, NULL, "foo", 2, foo_fields); /* Build the test function. */ @@ -52,7 +52,9 @@ create_code (gcc_jit_context *ctxt, void *user_data) 0, NULL, 0); gcc_jit_lvalue *tmp = - gcc_jit_function_new_local (test_fn, NULL, struct_foo, "tmp"); + gcc_jit_function_new_local (test_fn, NULL, + gcc_jit_struct_as_type (struct_foo), + "tmp"); /* Erroneous: tmp->x = ... */ gcc_jit_lvalue *lvalue = diff --git a/gcc/testsuite/jit.dg/test-fuzzer.c b/gcc/testsuite/jit.dg/test-fuzzer.c index 7fbb5a2..11c1db5 100644 --- a/gcc/testsuite/jit.dg/test-fuzzer.c +++ b/gcc/testsuite/jit.dg/test-fuzzer.c @@ -212,14 +212,14 @@ make_random_type (fuzzer *f) } char struct_name[256]; sprintf (struct_name, "s%i", f->num_types); - gcc_jit_type *struct_ = \ + gcc_jit_struct *struct_ = \ gcc_jit_context_new_struct_type (f->ctxt, get_random_location (f), struct_name, num_fields, fields); free (fields); - return struct_; + return gcc_jit_struct_as_type (struct_); } } } diff --git a/gcc/testsuite/jit.dg/test-linked-list.c b/gcc/testsuite/jit.dg/test-linked-list.c new file mode 100644 index 0000000..b925b9e --- /dev/null +++ b/gcc/testsuite/jit.dg/test-linked-list.c @@ -0,0 +1,133 @@ +#include <stdlib.h> +#include <stdio.h> + +#include "libgccjit.h" + +#include "harness.h" + +/* A doubly-linked list, to ensure that the JIT API can cope with + self-referential types. */ +struct node +{ + struct node *prev; + struct node *next; + int value; +}; + +void +create_code (gcc_jit_context *ctxt, void *user_data) +{ + /* Let's try to inject the equivalent of: + int + test_linked_list (struct node *n) + { + int total = 0; + while (n) + { + total += n->value; + n = n->next; + } + return total; + } + */ + gcc_jit_type *t_int = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); + gcc_jit_struct *t_node = + gcc_jit_context_new_opaque_struct (ctxt, NULL, "node"); + gcc_jit_type *t_node_ptr = + gcc_jit_type_get_pointer (gcc_jit_struct_as_type (t_node)); + + gcc_jit_field *f_prev = + gcc_jit_context_new_field (ctxt, NULL, t_node_ptr, "prev"); + gcc_jit_field *f_next = + gcc_jit_context_new_field (ctxt, NULL, t_node_ptr, "next"); + gcc_jit_field *f_value = + gcc_jit_context_new_field (ctxt, NULL, t_int, "value"); + gcc_jit_field *fields[] = {f_prev, f_next, f_value}; + gcc_jit_struct_set_fields (t_node, NULL, 3, fields); + + /* Build the test function. */ + gcc_jit_param *param_n = + gcc_jit_context_new_param (ctxt, NULL, t_node_ptr, "n"); + gcc_jit_function *fn = + gcc_jit_context_new_function (ctxt, NULL, + GCC_JIT_FUNCTION_EXPORTED, + t_int, + "test_linked_list", + 1, ¶m_n, + 0); + /* int total; */ + gcc_jit_lvalue *total = + gcc_jit_function_new_local (fn, NULL, t_int, "total"); + + /* total = 0; */ + gcc_jit_function_add_assignment ( + fn, NULL, + total, + gcc_jit_context_zero (ctxt, t_int)); + + /* while (n) */ + gcc_jit_loop *loop = + gcc_jit_function_new_loop ( + fn, NULL, + gcc_jit_context_new_comparison (ctxt, NULL, + GCC_JIT_COMPARISON_NE, + gcc_jit_param_as_rvalue (param_n), + gcc_jit_context_null (ctxt, t_node_ptr))); + + /* total += n->value; */ + gcc_jit_function_add_assignment_op ( + fn, NULL, + total, + GCC_JIT_BINARY_OP_PLUS, + gcc_jit_lvalue_as_rvalue ( + gcc_jit_rvalue_dereference_field ( + gcc_jit_param_as_rvalue (param_n), + NULL, + f_value))); + + /* n = n->next; */ + gcc_jit_function_add_assignment ( + fn, NULL, + gcc_jit_param_as_lvalue (param_n), + gcc_jit_lvalue_as_rvalue ( + gcc_jit_rvalue_dereference_field ( + gcc_jit_param_as_rvalue (param_n), + NULL, + f_next))); + + gcc_jit_loop_end (loop, NULL); + + /* return total; */ + gcc_jit_function_add_return (fn, NULL, gcc_jit_lvalue_as_rvalue (total)); +} + +void +verify_code (gcc_jit_context *ctxt, gcc_jit_result *result) +{ + struct node a, b, c; + typedef int (*fn_type) (struct node *n); + CHECK_NON_NULL (result); + + fn_type test_linked_list = + (fn_type)gcc_jit_result_get_code (result, "test_linked_list"); + CHECK_NON_NULL (test_linked_list); + + /* Construct a simple linked-list on the stack: a->b->c: */ + a.prev = NULL; + a.next = &b; + a.value = 5; + + b.prev = &a; + b.next = &c; + b.value = 3; + + c.prev = &b; + c.next = NULL; + c.value = 7; + + CHECK_VALUE (test_linked_list (NULL), 0); + CHECK_VALUE (test_linked_list (&a), 15); + CHECK_VALUE (test_linked_list (&b), 10); + CHECK_VALUE (test_linked_list (&c), 7); +} diff --git a/gcc/testsuite/jit.dg/test-nested-contexts.c b/gcc/testsuite/jit.dg/test-nested-contexts.c index eaedd75..d24a859 100644 --- a/gcc/testsuite/jit.dg/test-nested-contexts.c +++ b/gcc/testsuite/jit.dg/test-nested-contexts.c @@ -136,8 +136,9 @@ make_types (struct top_level *top_level) top_level->c, top_level->discriminant}; top_level->struct_quadratic = - gcc_jit_context_new_struct_type (top_level->ctxt, NULL, - "quadratic", 4, fields); + gcc_jit_struct_as_type ( + gcc_jit_context_new_struct_type (top_level->ctxt, NULL, + "quadratic", 4, fields)); top_level->quadratic_ptr = gcc_jit_type_get_pointer (top_level->struct_quadratic); } diff --git a/gcc/testsuite/jit.dg/test-quadratic.c b/gcc/testsuite/jit.dg/test-quadratic.c index 9b02c06..337bea5 100644 --- a/gcc/testsuite/jit.dg/test-quadratic.c +++ b/gcc/testsuite/jit.dg/test-quadratic.c @@ -115,8 +115,9 @@ make_types (struct quadratic_test *testcase) testcase->c, testcase->discriminant}; testcase->quadratic = - gcc_jit_context_new_struct_type (testcase->ctxt, NULL, - "quadratic", 4, fields); + gcc_jit_struct_as_type ( + gcc_jit_context_new_struct_type (testcase->ctxt, NULL, + "quadratic", 4, fields)); testcase->quadratic_ptr = gcc_jit_type_get_pointer (testcase->quadratic); } diff --git a/gcc/testsuite/jit.dg/test-reading-struct.c b/gcc/testsuite/jit.dg/test-reading-struct.c index fd53f84..4214320 100644 --- a/gcc/testsuite/jit.dg/test-reading-struct.c +++ b/gcc/testsuite/jit.dg/test-reading-struct.c @@ -45,7 +45,8 @@ create_code (gcc_jit_context *ctxt, void *user_data) "y"); gcc_jit_field *fields[] = {x, y}; gcc_jit_type *struct_type = - gcc_jit_context_new_struct_type (ctxt, NULL, "bar", 2, fields); + gcc_jit_struct_as_type ( + gcc_jit_context_new_struct_type (ctxt, NULL, "bar", 2, fields)); gcc_jit_type *const_struct_type = gcc_jit_type_get_const (struct_type); gcc_jit_type *ptr_type = gcc_jit_type_get_pointer (const_struct_type); diff --git a/gcc/testsuite/jit.dg/test-types.c b/gcc/testsuite/jit.dg/test-types.c index f6fc1b2..575176f 100644 --- a/gcc/testsuite/jit.dg/test-types.c +++ b/gcc/testsuite/jit.dg/test-types.c @@ -161,12 +161,13 @@ create_code (gcc_jit_context *ctxt, void *user_data) }; gcc_jit_type *zoo_type = - gcc_jit_context_new_struct_type ( - ctxt, - NULL, - "zoo", - sizeof (zoo_fields) / sizeof (zoo_fields[0]), - zoo_fields); + gcc_jit_struct_as_type ( + gcc_jit_context_new_struct_type ( + ctxt, + NULL, + "zoo", + sizeof (zoo_fields) / sizeof (zoo_fields[0]), + zoo_fields)); gcc_jit_type *zoo_ptr_type = gcc_jit_type_get_pointer (zoo_type); -- 1.7.11.7