summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRico Tzschichholz <ricotz@ubuntu.com>2021-11-27 19:26:35 +0100
committerRico Tzschichholz <ricotz@ubuntu.com>2021-11-27 19:26:35 +0100
commit0e097710e37b671b17ed1da330dd83b9e2340602 (patch)
tree976a1d3488459b7946c742a3185ab69fd33acb1d
parent05d804ba387d8231552615fcbb69f3ce457d3ef6 (diff)
downloadvala-0e097710e37b671b17ed1da330dd83b9e2340602.tar.gz
codegen: Accept CCode.type attribute on parameters
Fixes https://gitlab.gnome.org/GNOME/vala/issues/876
-rw-r--r--codegen/valaccodearraymodule.vala22
-rw-r--r--codegen/valaccodemethodmodule.vala31
-rw-r--r--codegen/valagtypemodule.vala9
-rw-r--r--tests/methods/parameter-ccode-type.c-expected185
-rw-r--r--tests/methods/parameter-ccode-type.vala51
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);
+ }
+}