summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavel Holejsovsky <pholejs@src.gnome.org>2011-01-09 16:12:46 +0100
committerPavel Holejsovsky <pholejs@src.gnome.org>2011-01-13 16:28:05 +0100
commit8896eb04d9cb9f8792da34ae9814c7d7b97a9729 (patch)
treed8d49c81ed5961929ad88b0f17f045d89e818191
parentf3f3cb62abec946f82fe44a8382a04b28d6c7313 (diff)
downloadgobject-introspection-8896eb04d9cb9f8792da34ae9814c7d7b97a9729.tar.gz
Make caller-allocates detection work for struct aliases
Scanner tries to detect caller-allocates attribute automatically if not explicitly specified by checking that parameter is not double-referenced and is struct or union. This patch adds resolving of aliases when checking whether parameter is struct or union. Also removes old incorrect method transformer.follow_aliases, which was never used in current code. Fixes https://bugzilla.gnome.org/show_bug.cgi?id=639081
-rw-r--r--giscanner/maintransformer.py1
-rw-r--r--giscanner/transformer.py17
-rw-r--r--tests/scanner/Regress-1.0-expected.gir18
-rw-r--r--tests/scanner/regress.c10
-rw-r--r--tests/scanner/regress.h9
5 files changed, 48 insertions, 7 deletions
diff --git a/giscanner/maintransformer.py b/giscanner/maintransformer.py
index 0868d785..345f0f0e 100644
--- a/giscanner/maintransformer.py
+++ b/giscanner/maintransformer.py
@@ -501,6 +501,7 @@ usage is void (*_gtk_reserved1)(void);"""
if subtype in (None, ''):
if node.type.target_giname and node.type.ctype:
target = self._transformer.lookup_giname(node.type.target_giname)
+ target = self._transformer.resolve_aliases(target)
has_double_indirection = '**' in node.type.ctype
is_structure_or_union = isinstance(target, (ast.Record, ast.Union))
caller_allocates = (not has_double_indirection and is_structure_or_union)
diff --git a/giscanner/transformer.py b/giscanner/transformer.py
index 4cd24484..a651649a 100644
--- a/giscanner/transformer.py
+++ b/giscanner/transformer.py
@@ -827,12 +827,15 @@ Note that type resolution may not succeed."""
else:
return None
- def follow_aliases(self, type_name, names):
- while True:
- resolved = names.aliases.get(type_name)
- if resolved:
- (ns, alias) = resolved
- type_name = alias.target
+ def resolve_aliases(self, typenode):
+ """Removes all aliases from typenode, returns first non-alias
+ in the typenode alias chain. Returns typenode argument if it
+ is not an alias."""
+ while isinstance(typenode, ast.Alias):
+ if typenode.target.target_giname is not None:
+ typenode = self.lookup_giname(typenode.target.target_giname)
+ elif typenode.target.target_fundamental is not None:
+ typenode = ast.type_names[typenode.target.target_fundamental]
else:
break
- return type_name
+ return typenode
diff --git a/tests/scanner/Regress-1.0-expected.gir b/tests/scanner/Regress-1.0-expected.gir
index c7fb7835..3d4e56f7 100644
--- a/tests/scanner/Regress-1.0-expected.gir
+++ b/tests/scanner/Regress-1.0-expected.gir
@@ -16,6 +16,10 @@ and/or use gtk-doc annotations. -->
shared-library="libregress.so"
c:identifier-prefixes="Regress"
c:symbol-prefixes="regress">
+ <alias name="AliasedTestBoxed" c:type="RegressAliasedTestBoxed">
+ <doc xml:whitespace="preserve">Typedef TestBoxed to test caller-allocates correctness</doc>
+ <type name="TestBoxed" c:type="RegressTestBoxed"/>
+ </alias>
<alias name="IntSet" c:type="RegressIntSet" introspectable="0">
<doc xml:whitespace="preserve">Compatibility typedef, like telepathy-glib's TpIntSet</doc>
<type name="Intset" c:type="RegressIntset"/>
@@ -963,6 +967,20 @@ TpAccount::status-changed</doc>
<type name="GObject.Object" c:type="GObject*"/>
</field>
</record>
+ <function name="aliased_caller_alloc"
+ c:identifier="regress_aliased_caller_alloc">
+ <return-value transfer-ownership="none">
+ <type name="none" c:type="void"/>
+ </return-value>
+ <parameters>
+ <parameter name="boxed"
+ direction="out"
+ caller-allocates="1"
+ transfer-ownership="none">
+ <type name="AliasedTestBoxed" c:type="RegressAliasedTestBoxed*"/>
+ </parameter>
+ </parameters>
+ </function>
<function name="func_obj_null_in" c:identifier="regress_func_obj_null_in">
<return-value transfer-ownership="none">
<type name="none" c:type="void"/>
diff --git a/tests/scanner/regress.c b/tests/scanner/regress.c
index faac481e..f9c4b371 100644
--- a/tests/scanner/regress.c
+++ b/tests/scanner/regress.c
@@ -2889,3 +2889,13 @@ void
regress_not_introspectable_via_alias (RegressVaListAlias ok)
{
}
+
+/**
+ * regress_aliased_caller_alloc:
+ * @boxed: (out):
+ */
+void regress_aliased_caller_alloc (RegressAliasedTestBoxed *boxed)
+{
+ boxed->priv = g_slice_new0 (RegressTestBoxedPrivate);
+ boxed->priv->magic = 0xdeadbeef;
+}
diff --git a/tests/scanner/regress.h b/tests/scanner/regress.h
index 5f82bbce..2a3b3516 100644
--- a/tests/scanner/regress.h
+++ b/tests/scanner/regress.h
@@ -579,6 +579,15 @@ typedef va_list RegressVaListAlias;
void regress_not_introspectable_via_alias (RegressVaListAlias ok);
+/**
+ * RegressAliasedTestBoxed:
+ *
+ * Typedef TestBoxed to test caller-allocates correctness
+ */
+typedef RegressTestBoxed RegressAliasedTestBoxed;
+
+void regress_aliased_caller_alloc (RegressAliasedTestBoxed *boxed);
+
/* private testing */
typedef struct {