- def _create_typedef_struct(self, symbol, disguised=False):
- try:
- name = self.strip_identifier(symbol.ident)
- except TransformerException, e:
- message.warn_symbol(symbol, e)
- return None
- struct = ast.Record(name, symbol.ident, disguised)
- self._parse_fields(symbol, struct)
- struct.add_symbol_reference(symbol)
- self._typedefs_ns[symbol.ident] = struct
- return None
+ def _create_typedef_compound(self, compound_class, symbol, disguised=False):
+ name = self.strip_identifier(symbol.ident)
+ assert symbol.base_type
+ if symbol.base_type.name:
+ tag_name = symbol.base_type.name
+ else:
+ tag_name = None
+
+ # If the struct already exists in the tag namespace, use it.
+ if tag_name in self._tag_ns:
+ compound = self._tag_ns[tag_name]
+ if compound.name:
+ # If the struct name is set it means the struct has already been
+ # promoted from the tag namespace to the main namespace by a
+ # prior typedef struct. If we get here it means this is another
+ # typedef of that struct. Instead of creating an alias to the
+ # primary typedef that has been promoted, we create a new Record
+ # with shared fields. This handles the case where we want to
+ # give structs like GInitiallyUnowned its own Record:
+ # typedef struct _GObject GObject;
+ # typedef struct _GObject GInitiallyUnowned;
+ # See: http://bugzilla.gnome.org/show_bug.cgi?id=569408
+ new_compound = compound_class(name, symbol.ident, tag_name=tag_name)
+ new_compound.fields = compound.fields
+ new_compound.add_symbol_reference(symbol)
+ return new_compound
+ else:
+ # If the struct does not have its name set, it exists only in
+ # the tag namespace. Set it here and return it which will
+ # promote it to the main namespace. Essentially the first
+ # typedef for a struct clobbers its name and ctype which is what
+ # will be visible to GI.
+ compound.name = name
+ compound.ctype = symbol.ident
+ else:
+ # Create a new struct with a typedef name and tag name when available.
+ # Structs with a typedef name are promoted into the main namespace
+ # by it being returned to the "parse" function and are also added to
+ # the tag namespace if it has a tag_name set.
+ compound = compound_class(name, symbol.ident, disguised=disguised, tag_name=tag_name)
+ if tag_name:
+ # Force the struct as disguised for now since we do not yet know
+ # if it has fields that will be parsed. Note that this is using
+ # an erroneous definition of disguised and we should eventually
+ # only look at the field count when needed.
+ compound.disguised = True
+ else:
+ # Case where we have an anonymous struct which is typedef'd:
+ # typedef struct {...} Struct;
+ # we need to parse the fields because we never get a struct
+ # in the tag namespace which is normally where fields are parsed.
+ self._parse_fields(symbol, compound)