diff options
author | Rico Tzschichholz <ricotz@ubuntu.com> | 2021-11-27 19:26:35 +0100 |
---|---|---|
committer | Rico Tzschichholz <ricotz@ubuntu.com> | 2021-11-27 19:26:35 +0100 |
commit | 0e097710e37b671b17ed1da330dd83b9e2340602 (patch) | |
tree | 976a1d3488459b7946c742a3185ab69fd33acb1d | |
parent | 05d804ba387d8231552615fcbb69f3ce457d3ef6 (diff) | |
download | vala-0e097710e37b671b17ed1da330dd83b9e2340602.tar.gz |
codegen: Accept CCode.type attribute on parameters
Fixes https://gitlab.gnome.org/GNOME/vala/issues/876
-rw-r--r-- | codegen/valaccodearraymodule.vala | 22 | ||||
-rw-r--r-- | codegen/valaccodemethodmodule.vala | 31 | ||||
-rw-r--r-- | codegen/valagtypemodule.vala | 9 | ||||
-rw-r--r-- | tests/methods/parameter-ccode-type.c-expected | 185 | ||||
-rw-r--r-- | tests/methods/parameter-ccode-type.vala | 51 |
5 files changed, 271 insertions, 27 deletions
diff --git a/codegen/valaccodearraymodule.vala b/codegen/valaccodearraymodule.vala index 770b4a727..b2707ff8d 100644 --- a/codegen/valaccodearraymodule.vala +++ b/codegen/valaccodearraymodule.vala @@ -850,23 +850,25 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule { } public override CCodeParameter generate_parameter (Parameter param, CCodeFile decl_space, Map<int,CCodeParameter> cparam_map, Map<int,CCodeExpression>? carg_map) { - if (param.params_array || !(param.variable_type is ArrayType)) { + unowned ArrayType? array_type = param.variable_type as ArrayType; + if (array_type == null || param.params_array) { return base.generate_parameter (param, decl_space, cparam_map, carg_map); } - string ctypename = get_ccode_name (param.variable_type); - string name = get_ccode_name (param); - var array_type = (ArrayType) param.variable_type; + string? ctypename = get_ccode_type (param); + if (ctypename == null) { + ctypename = get_ccode_name (param.variable_type); - if (array_type.fixed_length) { - ctypename += "*"; - } + if (array_type.fixed_length) { + ctypename += "*"; + } - if (param.direction != ParameterDirection.IN) { - ctypename += "*"; + if (param.direction != ParameterDirection.IN) { + ctypename += "*"; + } } - var main_cparam = new CCodeParameter (name, ctypename); + var main_cparam = new CCodeParameter (get_ccode_name (param), ctypename); generate_type_declaration (array_type.element_type, decl_space); diff --git a/codegen/valaccodemethodmodule.vala b/codegen/valaccodemethodmodule.vala index 840aa14bc..4bc754bb7 100644 --- a/codegen/valaccodemethodmodule.vala +++ b/codegen/valaccodemethodmodule.vala @@ -872,26 +872,29 @@ public abstract class Vala.CCodeMethodModule : CCodeStructModule { public virtual CCodeParameter generate_parameter (Parameter param, CCodeFile decl_space, Map<int,CCodeParameter> cparam_map, Map<int,CCodeExpression>? carg_map) { CCodeParameter cparam; if (!param.ellipsis && !param.params_array) { - string ctypename = get_ccode_name (param.variable_type); - generate_type_declaration (param.variable_type, decl_space); - // pass non-simple structs always by reference - unowned Struct? st = param.variable_type.type_symbol as Struct; - if (st != null) { - if (!st.is_simple_type () && param.direction == ParameterDirection.IN) { - if (st.is_immutable && !param.variable_type.value_owned) { - ctypename = "const " + ctypename; - } + string? ctypename = get_ccode_type (param); + if (ctypename == null) { + ctypename = get_ccode_name (param.variable_type); + + // pass non-simple structs always by reference + unowned Struct? st = param.variable_type.type_symbol as Struct; + if (st != null) { + if (!st.is_simple_type () && param.direction == ParameterDirection.IN) { + if (st.is_immutable && !param.variable_type.value_owned) { + ctypename = "const " + ctypename; + } - if (!param.variable_type.nullable) { - ctypename += "*"; + if (!param.variable_type.nullable) { + ctypename += "*"; + } } } - } - if (param.direction != ParameterDirection.IN) { - ctypename += "*"; + if (param.direction != ParameterDirection.IN) { + ctypename += "*"; + } } cparam = new CCodeParameter (get_ccode_name (param), ctypename); diff --git a/codegen/valagtypemodule.vala b/codegen/valagtypemodule.vala index e921eb295..270548e72 100644 --- a/codegen/valagtypemodule.vala +++ b/codegen/valagtypemodule.vala @@ -31,10 +31,13 @@ public class Vala.GTypeModule : GErrorModule { generate_type_declaration (param.variable_type, decl_space); - string ctypename = get_ccode_name (param.variable_type); + string? ctypename = get_ccode_type (param); + if (ctypename == null) { + ctypename = get_ccode_name (param.variable_type); - if (param.direction != ParameterDirection.IN) { - ctypename = "%s*".printf (ctypename); + if (param.direction != ParameterDirection.IN) { + ctypename = "%s*".printf (ctypename); + } } var cparam = new CCodeParameter (get_ccode_name (param), ctypename); diff --git a/tests/methods/parameter-ccode-type.c-expected b/tests/methods/parameter-ccode-type.c-expected new file mode 100644 index 000000000..1718ba5dc --- /dev/null +++ b/tests/methods/parameter-ccode-type.c-expected @@ -0,0 +1,185 @@ +/* methods_parameter_ccode_type.c generated by valac, the Vala compiler + * generated from methods_parameter_ccode_type.vala, do not modify */ + +#include <stdlib.h> +#include <string.h> +#include <glib.h> +#include <glib-object.h> + +#if !defined(VALA_EXTERN) +#if defined(_MSC_VER) +#define VALA_EXTERN __declspec(dllexport) extern +#elif __GNUC__ >= 4 +#define VALA_EXTERN __attribute__((visibility("default"))) extern +#else +#define VALA_EXTERN extern +#endif +#endif + +#define _vala_assert(expr, msg) if G_LIKELY (expr) ; else g_assertion_message_expr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg); +#define _vala_return_if_fail(expr, msg) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return; } +#define _vala_return_val_if_fail(expr, msg, val) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return val; } +#define _vala_warn_if_fail(expr, msg) if G_LIKELY (expr) ; else g_warn_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg); + +VALA_EXTERN void foo (const gchar** sa); +VALA_EXTERN void bar (const gchar*** sa); +VALA_EXTERN void manam (const GObject** oa); +VALA_EXTERN void faz (const GObject* o); +VALA_EXTERN void baz (const GObject** o); +VALA_EXTERN void minim (gpointer* p); +static void _vala_main (void); +static void _vala_array_destroy (gpointer array, + gssize array_length, + GDestroyNotify destroy_func); +static void _vala_array_free (gpointer array, + gssize array_length, + GDestroyNotify destroy_func); + +const gchar* BARS[3] = {"foo", "bar", NULL}; + +void +foo (const gchar** sa) +{ + const gchar* _tmp0_; + _tmp0_ = sa[1]; + _vala_assert (g_strcmp0 (_tmp0_, "bar") == 0, "sa[1] == \"bar\""); +} + +void +bar (const gchar*** sa) +{ + gchar** _vala_sa = NULL; + gint _vala_sa_length1 = 0; + _vala_sa = (const gchar***) BARS; + if (sa) { + *sa = _vala_sa; + } +} + +void +manam (const GObject** oa) +{ + GObject* _tmp0_; + _tmp0_ = oa[1]; + _vala_assert (_tmp0_ == NULL, "oa[1] == null"); +} + +void +faz (const GObject* o) +{ + g_return_if_fail ((o == NULL) || G_TYPE_CHECK_INSTANCE_TYPE (o, G_TYPE_OBJECT)); + _vala_assert (o == NULL, "o == null"); +} + +void +baz (const GObject** o) +{ + GObject* _vala_o = NULL; + _vala_o = (const GObject**) NULL; + if (o) { + *o = _vala_o; + } +} + +void +minim (gpointer* p) +{ + void* _vala_p = NULL; + _vala_p = (gpointer*) NULL; + if (p) { + *p = _vala_p; + } +} + +static void +_vala_main (void) +{ + { + gchar* _tmp0_; + gchar* _tmp1_; + gchar** _tmp2_; + gchar** _tmp3_; + gint _tmp3__length1; + _tmp0_ = g_strdup ("foo"); + _tmp1_ = g_strdup ("bar"); + _tmp2_ = g_new0 (gchar*, 3 + 1); + _tmp2_[0] = _tmp0_; + _tmp2_[1] = _tmp1_; + _tmp2_[2] = NULL; + _tmp3_ = _tmp2_; + _tmp3__length1 = 3; + foo ((const gchar**) _tmp3_); + _tmp3_ = (_vala_array_free (_tmp3_, _tmp3__length1, (GDestroyNotify) g_free), NULL); + } + { + gchar** sa = NULL; + gint sa_length1 = 0; + gint _sa_size_ = 0; + gchar** _tmp4_ = NULL; + bar ((const gchar***) (&_tmp4_)); + sa = _tmp4_; + sa_length1 = -1; + _sa_size_ = sa_length1; + } + { + GObject** _tmp5_; + GObject** _tmp6_; + gint _tmp6__length1; + _tmp5_ = g_new0 (GObject*, 1 + 1); + _tmp5_[0] = NULL; + _tmp6_ = _tmp5_; + _tmp6__length1 = 1; + manam ((const GObject**) _tmp6_); + _tmp6_ = (_vala_array_free (_tmp6_, _tmp6__length1, (GDestroyNotify) g_object_unref), NULL); + } + { + faz ((const GObject*) NULL); + } + { + GObject* o = NULL; + GObject* _tmp7_ = NULL; + baz ((const GObject**) (&_tmp7_)); + o = _tmp7_; + _vala_assert (o == NULL, "o == null"); + } + { + void* p = NULL; + void* _tmp8_ = NULL; + minim ((gpointer*) (&_tmp8_)); + p = _tmp8_; + _vala_assert (p == NULL, "p == null"); + } +} + +int +main (int argc, + char ** argv) +{ + _vala_main (); + return 0; +} + +static void +_vala_array_destroy (gpointer array, + gssize array_length, + GDestroyNotify destroy_func) +{ + if ((array != NULL) && (destroy_func != NULL)) { + gssize i; + for (i = 0; i < array_length; i = i + 1) { + if (((gpointer*) array)[i] != NULL) { + destroy_func (((gpointer*) array)[i]); + } + } + } +} + +static void +_vala_array_free (gpointer array, + gssize array_length, + GDestroyNotify destroy_func) +{ + _vala_array_destroy (array, array_length, destroy_func); + g_free (array); +} + diff --git a/tests/methods/parameter-ccode-type.vala b/tests/methods/parameter-ccode-type.vala new file mode 100644 index 000000000..c9f7206fa --- /dev/null +++ b/tests/methods/parameter-ccode-type.vala @@ -0,0 +1,51 @@ +void foo ([CCode (array_length = false, type = "const gchar**")] string[]? sa) { + assert (sa[1] == "bar"); +} + +const string[] BARS = { "foo", "bar", null }; + +void bar ([CCode (array_length = false, type = "const gchar***")] out unowned string[]? sa) { + sa = BARS; +} + +void manam ([CCode (array_length = false, type = "const GObject**")] Object[]? oa) { + assert (oa[1] == null); +} + +void faz ([CCode (type = "const GObject*")] Object? o) { + assert (o == null); +} + +void baz ([CCode (type = "const GObject**")] out unowned Object? o) { + o = null ; +} + +void minim ([CCode (type = "gpointer*")] out unowned void* p) { + p = null; +} + +void main () { + { + foo ({ "foo", "bar", null }); + } + { + unowned string[] sa; + bar (out sa); + } + { + manam ({ null }); + } + { + faz (null); + } + { + unowned Object? o; + baz (out o); + assert (o == null); + } + { + unowned void* p; + minim (out p); + assert (p == null); + } +} |