+struct type_struct {
+ struct type p;
+ GHashTable *fields_by_name; /* Tuples (field name, field index) */
+ struct type_scope *scope;
+ GArray *fields; /* Array of type_field */
+};
+
+struct declaration_struct {
+ struct declaration p;
+ struct type_struct *type;
+ struct declaration_scope *scope;
+ GArray *fields; /* Array of struct field */
+};
+
+struct type_variant {
+ struct type p;
+ GHashTable *fields_by_tag; /* Tuples (field tag, field index) */
+ struct type_scope *scope;
+ GArray *fields; /* Array of type_field */
+ GQuark tag_name; /* TODO */
+ /* Tag name must be nonzero and must exist when defining the variant */
+};
+
+struct declaration_variant {
+ struct declaration p;
+ struct type_variant *type;
+ struct declaration_scope *scope;
+ struct declaration *enum_tag;
+ GArray *fields; /* Array of struct field */
+ struct field *current_field; /* Last field read */
+};
+
+struct type_array {
+ struct type p;
+ size_t len;
+ struct type *elem;
+ struct type_scope *scope;
+};
+
+struct declaration_array {
+ struct declaration p;
+ struct type_array *type;
+ struct declaration_scope *scope;
+ struct field current_element; /* struct field */
+};
+
+struct type_sequence {
+ struct type p;
+ struct type_integer *len_type;
+ struct type *elem;
+ struct type_scope *scope;
+};
+
+struct declaration_sequence {
+ struct declaration p;
+ struct type_sequence *type;
+ struct declaration_scope *scope;
+ struct declaration_integer *len;
+ struct field current_element; /* struct field */
+};
+
+/*
+ * type_declaration is for typedef and typealias. They are registered
+ * into type scopes.
+ */
+int register_type_declaration(GQuark type_name, struct declaration *declaration,
+ struct type_scope *scope);
+struct declaration *lookup_type_declaration(GQuark type_name,
+ struct type_scope *scope);
+
+/*
+ * Type scopes also contain a separate registry for struct, variant and
+ * enum types. Those register types rather than type declarations, so
+ * that a named variant can be declared without specifying its target
+ * "choice" tag field immediately.
+ */
+int register_struct_type(GQuark struct_name, struct type_struct *struct_type,
+ struct type_scope *scope);
+struct type_struct *lookup_struct_type(GQuark struct_name,
+ struct type_scope *scope);
+int register_variant_type(GQuark variant_name,
+ struct type_variant *variant_type,
+ struct type_scope *scope);
+struct type_variant *lookup_variant_type(GQuark variant_name,
+ struct type_scope *scope);
+int register_enum_type(GQuark enum_name, struct type_enum *enum_type,
+ struct type_scope *scope);
+struct type_enum *lookup_enum_type(GQuark enum_name,
+ struct type_scope *scope);
+
+struct type_scope *new_type_scope(struct type_scope *parent_scope);
+void free_type_scope(struct type_scope *scope);
+
+/*
+ * field_declaration is for field declarations. They are registered into
+ * declaration scopes.
+ */
+struct declaration *
+ lookup_field_declaration(GQuark field_name,
+ struct declaration_scope *scope);
+int register_field_declaration(GQuark field_name,
+ struct declaration *declaration,
+ struct declaration_scope *scope);
+struct declaration_scope *
+ new_declaration_scope(struct declaration_scope *parent_scope);
+void free_declaration_scope(struct declaration_scope *scope);
+
+void type_ref(struct type *type);
+void type_unref(struct type *type);
+
+void declaration_ref(struct declaration *declaration);
+void declaration_unref(struct declaration *declaration);
+
+/* Nameless types can be created by passing a NULL name */
+
+struct type_integer *integer_type_new(const char *name,
+ size_t len, int byte_order,
+ int signedness, size_t alignment);
+
+/*
+ * mantissa_len is the length of the number of bytes represented by the mantissa
+ * (e.g. result of DBL_MANT_DIG). It includes the leading 1.
+ */
+struct type_float *float_type_new(const char *name,
+ size_t mantissa_len,
+ size_t exp_len, int byte_order,
+ size_t alignment);