Bug 569408, Bug 568680 - Scanner misses fields (at least in GObject.Object)
authorColin Walters <walters@src.gnome.org>
Mon, 2 Feb 2009 16:31:06 +0000 (16:31 +0000)
committerColin Walters <walters@src.gnome.org>
Mon, 2 Feb 2009 16:31:06 +0000 (16:31 +0000)
The scanner misses all fields of the GObject struct -- there
are no <field> children of the <class> element for GObject in the GIR. This of
course yields wrong field offsets for all derived objects.

svn path=/trunk/; revision=1079

ChangeLog
gir/GObject-2.0.xpath [new file with mode: 0644]
gir/Makefile.am
girepository/giroffsets.c
giscanner/glibtransformer.py
giscanner/transformer.py
tests/offsets/Makefile.am
tests/offsets/offsets.h

index 8f1b793..3565473 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,32 @@
 2009-02-02  Andreas Rottmann  <a.rottmann@gmx.at>
 
+       Bug 569408 – Scanner doesn't handle arbitrary typedefs correctly
+
+       * giscanner/glibtransformer.py (GLibTransformer._create_gobject):
+       Treat GInitiallyUnowned specially.
+
+       Bug 568680 – Scanner misses fields (at least in GObject.Object)
+
+       * girepository/giroffsets.c (compute_struct_field_offsets): Fix
+       handling of callbacks (a callback member clobbered the size
+       computed so far).
+
+       * giscanner/transformer.py (Transformer._create_compound): Use
+       the (empty) compound created by a typedef if present; this means
+       that fields will no longer get lost.
+
+       * giscanner/transformer.py (Transformer._create_compound): New
+       method, contains logic common to _create_union and _create_struct.
+       (Transformer._create_struct, Transformer._create_union): Rewritten
+       in terms of _create_compound.
+
+       * gir/GObject-2.0.xpath: Some new assertations of the presence
+       GObject fields.
+       * tests/offsets/Makefile.am, tests/offsets/offsets.h: Added test
+       for object field offsets.
+
+  2009-02-02  Andreas Rottmann  <a.rottmann@gmx.at>
+
        Bug 563469 – Arrays not treated correctly in struct offset calculation
 
        * tests/offsets/offsets.h (OffsetsArray): New struct, containing a
diff --git a/gir/GObject-2.0.xpath b/gir/GObject-2.0.xpath
new file mode 100644 (file)
index 0000000..3a97543
--- /dev/null
@@ -0,0 +1,3 @@
+/namespace/class[@name='Object']/field[@name='g_type_instance']
+/namespace/class[@name='Object']/field[@name='ref_count']
+/namespace/class[@name='Object']/field[@name='qdata']
index c8c0ca4..1adccd5 100644 (file)
@@ -70,6 +70,8 @@ GObject-2.0.gir: GLib-2.0.gir $(SCANNER_BIN) $(SCANNER_LIBS) Makefile
            -DGOBJECT_COMPILATION \
             --pkg gobject-2.0 \
            $(GLIB_INCLUDEDIR)/gobject/*.h
+       $(SCANNER) $(SCANNER_ARGS) \
+           --xpath-assertions=$(srcdir)/GObject-2.0.xpath GObject-2.0.gir
 BUILT_GIRSOURCES += GObject-2.0.gir
 
 # gmodule
index f224e69..cc56d0b 100644 (file)
@@ -357,8 +357,9 @@ compute_struct_field_offsets (GIrNode     *node,
        }
       else if (member->type == G_IR_NODE_CALLBACK)
        {
-         size = ffi_type_pointer.size;
-         alignment = ffi_type_pointer.alignment;
+          size = ALIGN (size, ffi_type_pointer.alignment);
+          alignment = MAX (alignment, ffi_type_pointer.alignment);
+         size += ffi_type_pointer.size;
        }
     }
 
index b9d2369..51076a2 100644 (file)
@@ -261,8 +261,20 @@ class GLibTransformer(object):
             parent_type_name = 'GObject'
             parent_gitype = self._resolve_gtypename(parent_type_name)
             symbol = 'g_initially_unowned_get_type'
+        else:
+            assert False
         gnode = GLibObject(node.name, parent_gitype, type_name, symbol, True)
-        gnode.fields.extend(node.fields)
+        if type_name == 'GObject':
+            gnode.fields.extend(node.fields)
+        else:
+            # http://bugzilla.gnome.org/show_bug.cgi?id=569408
+            # GInitiallyUnowned is actually a typedef for GObject, but
+            # that's not reflected in the GIR, where it appears as a
+            # subclass (as it appears in the GType hierarchy).  So
+            # what we do here is copy all of the GObject fields into
+            # GInitiallyUnowned so that struct offset computation
+            # works correctly.
+            gnode.fields = self._names.names['Object'][1].fields
         self._add_attribute(gnode)
         self._register_internal_type(type_name, gnode)
 
index d31300e..1d781c6 100644 (file)
@@ -478,45 +478,33 @@ class Transformer(object):
         self._typedefs_ns[callback.name] = callback
         return callback
 
-    def _create_struct(self, symbol):
-        struct = self._typedefs_ns.get(symbol.ident, None)
-        if struct is None:
+    def _create_compound(self, klass, symbol):
+        compound = self._typedefs_ns.get(symbol.ident, None)
+        if compound is None:
             # This is a bit of a hack; really we should try
             # to resolve through the typedefs to find the real
             # name
             if symbol.ident.startswith('_'):
                 name = symbol.ident[1:]
+                compound = self._typedefs_ns.get(name, None)
             else:
                 name = symbol.ident
-            name = self.remove_prefix(name)
-            struct = Struct(name, symbol.ident)
+            if compound is None:
+                name = self.remove_prefix(name)
+                compound = klass(name, symbol.ident)
 
         for child in symbol.base_type.child_list:
             field = self._traverse_one(child)
             if field:
-                struct.fields.append(field)
+                compound.fields.append(field)
 
-        return struct
+        return compound
 
-    def _create_union(self, symbol):
-        union = self._typedefs_ns.get(symbol.ident, None)
-        if union is None:
-            # This is a bit of a hack; really we should try
-            # to resolve through the typedefs to find the real
-            # name
-            if symbol.ident.startswith('_'):
-                name = symbol.ident[1:]
-            else:
-                name = symbol.ident
-            name = self.remove_prefix(name)
-            union = Union(name, symbol.ident)
-
-        for child in symbol.base_type.child_list:
-            field = self._traverse_one(child)
-            if field:
-                union.fields.append(field)
+    def _create_struct(self, symbol):
+        return self._create_compound(Struct, symbol)
 
-        return union
+    def _create_union(self, symbol):
+        return self._create_compound(Union, symbol)
 
     def _create_callback(self, symbol):
         parameters = self._create_parameters(symbol.base_type.base_type)
index 8673aff..400d32a 100644 (file)
@@ -20,6 +20,7 @@ liboffsets_la_LDFLAGS = -avoid-version -rpath $(libdir)
 
 offsets-1.0.gir: liboffsets.la offsets.h $(SCANNER_BIN) $(SCANNER_LIBS) Makefile
        $(CHECK_DEBUG) $(SCANNER) \
+       --include=GObject-2.0 \
         --libtool="$(LIBTOOL)" \
        --library=offsets \
        --namespace=offsets \
@@ -51,7 +52,7 @@ CLEANFILES += gitestoffsets.c
 ############################################################
 
 check-local: offsets-1.0.typelib
-       LD_LIBRARY_PATH=$${LD_LIBRARY_PATH:+$$LD_LIBRARY_PATH:}$(builddir) GI_TYPELIB_PATH=$(builddir) \
+       LD_LIBRARY_PATH=$${LD_LIBRARY_PATH:+$$LD_LIBRARY_PATH:}$(builddir) GI_TYPELIB_PATH=$(builddir):$(top_builddir)/gir \
          $(builddir)/gitestoffsets$(EXEEXT) offsets.compiled offsets.introspected
        diff -u offsets.compiled offsets.introspected
 
index 9c29a98..3f887a8 100644 (file)
@@ -2,6 +2,7 @@
 #define __OFFSETS_H__
 
 #include <glib.h>
+#include <glib-object.h>
 #include <time.h>
 
 /* Test we get the alignment right for various basic types; we put
@@ -118,4 +119,22 @@ struct _OffsetsArray
   gpointer some_ptrs[5];
 };
 
+/** Test object offsets
+ */
+
+typedef struct _OffsetsObj OffsetsObj;
+typedef struct _OffsetsObjClass OffsetsObjClass;
+
+struct _OffsetsObj
+{
+  GObject parent_instance;
+
+  GObject *other;
+};
+
+struct _OffsetsObjClass
+{
+  GObjectClass parent_class;
+};
+
 #endif /* __OFFSETS_H__ */