+static
+struct definition *
+ lookup_typedef_declaration_scope(GQuark declaration_name,
+ struct declaration_scope *scope)
+{
+ return g_hash_table_lookup(scope->typedef_declarations,
+ (gconstpointer) (unsigned long) declaration_name);
+}
+
+struct definition *lookup_typedef_declaration(GQuark declaration_name,
+ struct declaration_scope *scope)
+{
+ struct definition *definition;
+
+ while (scope) {
+ definition = lookup_typedef_declaration_scope(declaration_name,
+ scope);
+ if (definition)
+ return definition;
+ scope = scope->parent_scope;
+ }
+ return NULL;
+}
+
+int register_typedef_declaration(GQuark name, struct declaration *declaration,
+ struct declaration_scope *scope)
+{
+ if (!name)
+ return -EPERM;
+
+ /* Only lookup in local scope */
+ if (lookup_typedef_declaration_scope(name, scope))
+ return -EEXIST;
+
+ g_hash_table_insert(scope->typedef_declarations,
+ (gpointer) (unsigned long) name,
+ declaration);
+ declaration_ref(declaration);
+ return 0;
+}
+
+static
+struct definition *
+ lookup_field_definition_scope(GQuark field_name,
+ struct definition_scope *scope)
+{
+ return g_hash_table_lookup(scope->definitions,
+ (gconstpointer) (unsigned long) field_name);
+}
+
+/*
+ * Returns the index at which the paths differ.
+ * If the value returned equals len, it means the paths are identical
+ * from index 0 to len-1.
+ */
+static int compare_paths(GArray *a, GArray *b, int len)
+{
+ int i;
+
+ assert(len <= a->len);
+ assert(len <= b->len);
+
+ for (i = 0; i < len; i++) {
+ GQuark qa, qb;
+
+ qa = g_array_index(a, GQuark, i);
+ qb = g_array_index(b, GQuark, i);
+ if (qa != qb)
+ return i;
+ }
+ return i;
+}
+
+static int is_path_child_of(GArray *path, GArray *maybe_parent)
+{
+ if (path->len <= maybe_parent->len)
+ return 0;
+ if (compare_paths(path, maybe_parent, maybe_parent->len)
+ == maybe_parent->len)
+ return 1;
+ else
+ return 0;
+}
+
+static struct definition_scope *
+ get_definition_scope(struct definition *definition)
+{
+ switch (definition->declaration->id) {
+ case CTF_TYPE_STRUCT:
+ {
+ struct definition_struct *def =
+ container_of(definition, struct definition_struct, p);
+ return def->scope;
+ }
+ case CTF_TYPE_VARIANT:
+ {
+ struct definition_variant *def =
+ container_of(definition, struct definition_variant, p);
+ return def->scope;
+ }
+ case CTF_TYPE_ARRAY:
+ {
+ struct definition_array *def =
+ container_of(definition, struct definition_array, p);
+ return def->scope;
+ }
+ case CTF_TYPE_SEQUENCE:
+ {
+ struct definition_sequence *def =
+ container_of(definition, struct definition_sequence, p);
+ return def->scope;
+ }
+
+ case CTF_TYPE_INTEGER:
+ case CTF_TYPE_FLOAT:
+ case CTF_TYPE_ENUM:
+ case CTF_TYPE_STRING:
+ case CTF_TYPE_UNKNOWN:
+ default:
+ return NULL;
+ }
+}
+