From 8896eb04d9cb9f8792da34ae9814c7d7b97a9729 Mon Sep 17 00:00:00 2001 From: Pavel Holejsovsky Date: Sun, 9 Jan 2011 16:12:46 +0100 Subject: [PATCH] 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 --- giscanner/maintransformer.py | 1 + giscanner/transformer.py | 17 ++++++++++------- tests/scanner/Regress-1.0-expected.gir | 18 ++++++++++++++++++ tests/scanner/regress.c | 10 ++++++++++ tests/scanner/regress.h | 9 +++++++++ 5 files changed, 48 insertions(+), 7 deletions(-) diff --git a/giscanner/maintransformer.py b/giscanner/maintransformer.py index 0868d78..345f0f0 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 4cd2448..a651649 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 c7fb783..3d4e56f 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"> + + Typedef TestBoxed to test caller-allocates correctness + + Compatibility typedef, like telepathy-glib's TpIntSet @@ -963,6 +967,20 @@ TpAccount::status-changed + + + + + + + + + + diff --git a/tests/scanner/regress.c b/tests/scanner/regress.c index faac481..f9c4b37 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 5f82bbc..2a3b351 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 { -- 2.7.4