+ g_hash_table_insert(scanner->cs->types, id->s, id->s);
+}
+
+static struct ctf_node *make_node(struct ctf_scanner *scanner,
+ enum node_type type)
+{
+ struct ctf_ast *ast = ctf_scanner_get_ast(scanner);
+ struct ctf_node *node;
+
+ node = malloc(sizeof(*node));
+ if (!node)
+ return NULL;
+ memset(node, 0, sizeof(*node));
+ node->type = type;
+ CDS_INIT_LIST_HEAD(&node->tmp_head);
+ cds_list_add(&node->gc, &ast->allocated_nodes);
+ cds_list_add(&node->siblings, &node->tmp_head);
+
+ switch (type) {
+ case NODE_ROOT:
+ fprintf(stderr, "[error] %s: trying to create root node\n", __func__);
+ break;
+
+ case NODE_EVENT:
+ CDS_INIT_LIST_HEAD(&node->u.event.declaration_list);
+ break;
+ case NODE_STREAM:
+ CDS_INIT_LIST_HEAD(&node->u.stream.declaration_list);
+ break;
+ case NODE_TRACE:
+ CDS_INIT_LIST_HEAD(&node->u.trace.declaration_list);
+ break;
+
+ case NODE_CTF_EXPRESSION:
+ CDS_INIT_LIST_HEAD(&node->u.ctf_expression.left);
+ CDS_INIT_LIST_HEAD(&node->u.ctf_expression.right);
+ break;
+ case NODE_UNARY_EXPRESSION:
+ break;
+
+ case NODE_TYPEDEF:
+ CDS_INIT_LIST_HEAD(&node->u._typedef.declaration_specifier);
+ CDS_INIT_LIST_HEAD(&node->u._typedef.type_declarators);
+ break;
+ case NODE_TYPEALIAS_TARGET:
+ CDS_INIT_LIST_HEAD(&node->u.typealias_target.declaration_specifier);
+ CDS_INIT_LIST_HEAD(&node->u.typealias_target.type_declarators);
+ break;
+ case NODE_TYPEALIAS_ALIAS:
+ CDS_INIT_LIST_HEAD(&node->u.typealias_alias.declaration_specifier);
+ CDS_INIT_LIST_HEAD(&node->u.typealias_alias.type_declarators);
+ break;
+ case NODE_TYPEALIAS:
+ break;
+
+ case NODE_TYPE_SPECIFIER:
+ break;
+ case NODE_POINTER:
+ break;
+ case NODE_TYPE_DECLARATOR:
+ CDS_INIT_LIST_HEAD(&node->u.type_declarator.pointers);
+ break;
+
+ case NODE_FLOATING_POINT:
+ CDS_INIT_LIST_HEAD(&node->u.floating_point.expressions);
+ break;
+ case NODE_INTEGER:
+ CDS_INIT_LIST_HEAD(&node->u.integer.expressions);
+ break;
+ case NODE_STRING:
+ CDS_INIT_LIST_HEAD(&node->u.string.expressions);
+ break;
+ case NODE_ENUMERATOR:
+ CDS_INIT_LIST_HEAD(&node->u.enumerator.values);
+ break;
+ case NODE_ENUM:
+ CDS_INIT_LIST_HEAD(&node->u._enum.enumerator_list);
+ break;
+ case NODE_STRUCT_OR_VARIANT_DECLARATION:
+ CDS_INIT_LIST_HEAD(&node->u.struct_or_variant_declaration.declaration_specifier);
+ CDS_INIT_LIST_HEAD(&node->u.struct_or_variant_declaration.type_declarators);
+ break;
+ case NODE_VARIANT:
+ CDS_INIT_LIST_HEAD(&node->u.variant.declaration_list);
+ break;
+ case NODE_STRUCT:
+ CDS_INIT_LIST_HEAD(&node->u._struct.declaration_list);
+ break;
+
+ case NODE_UNKNOWN:
+ default:
+ fprintf(stderr, "[error] %s: unknown node type %d\n", __func__,
+ (int) type);
+ break;
+ }
+
+ return node;
+}
+
+static int reparent_ctf_expression(struct ctf_node *node,
+ struct ctf_node *parent)
+{
+ switch (parent->type) {
+ case NODE_EVENT:
+ _cds_list_splice_tail(&node->tmp_head, &parent->u.event.declaration_list);
+ break;
+ case NODE_STREAM:
+ _cds_list_splice_tail(&node->tmp_head, &parent->u.stream.declaration_list);
+ break;
+ case NODE_TRACE:
+ _cds_list_splice_tail(&node->tmp_head, &parent->u.trace.declaration_list);
+ break;
+ case NODE_FLOATING_POINT:
+ _cds_list_splice_tail(&node->tmp_head, &parent->u.floating_point.expressions);
+ break;
+ case NODE_INTEGER:
+ _cds_list_splice_tail(&node->tmp_head, &parent->u.integer.expressions);
+ break;
+ case NODE_STRING:
+ _cds_list_splice_tail(&node->tmp_head, &parent->u.string.expressions);
+ break;
+
+ case NODE_ROOT:
+ case NODE_CTF_EXPRESSION:
+ case NODE_TYPEDEF:
+ case NODE_TYPEALIAS_TARGET:
+ case NODE_TYPEALIAS_ALIAS:
+ case NODE_TYPEALIAS:
+ case NODE_TYPE_SPECIFIER:
+ case NODE_POINTER:
+ case NODE_TYPE_DECLARATOR:
+ case NODE_ENUMERATOR:
+ case NODE_ENUM:
+ case NODE_STRUCT_OR_VARIANT_DECLARATION:
+ case NODE_VARIANT:
+ case NODE_STRUCT:
+ case NODE_UNARY_EXPRESSION:
+ return -EPERM;
+
+ case NODE_UNKNOWN:
+ default:
+ fprintf(stderr, "[error] %s: unknown node type %d\n", __func__,
+ (int) parent->type);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int reparent_typedef(struct ctf_node *node, struct ctf_node *parent)
+{
+ switch (parent->type) {
+ case NODE_ROOT:
+ _cds_list_splice_tail(&node->tmp_head, &parent->u.root._typedef);
+ break;
+ case NODE_EVENT:
+ _cds_list_splice_tail(&node->tmp_head, &parent->u.event.declaration_list);
+ break;
+ case NODE_STREAM:
+ _cds_list_splice_tail(&node->tmp_head, &parent->u.stream.declaration_list);
+ break;
+ case NODE_TRACE:
+ _cds_list_splice_tail(&node->tmp_head, &parent->u.trace.declaration_list);
+ break;
+ case NODE_VARIANT:
+ _cds_list_splice_tail(&node->tmp_head, &parent->u.variant.declaration_list);
+ break;
+ case NODE_STRUCT:
+ _cds_list_splice_tail(&node->tmp_head, &parent->u._struct.declaration_list);
+ break;
+
+ case NODE_FLOATING_POINT:
+ case NODE_INTEGER:
+ case NODE_STRING:
+ case NODE_CTF_EXPRESSION:
+ case NODE_TYPEDEF:
+ case NODE_TYPEALIAS_TARGET:
+ case NODE_TYPEALIAS_ALIAS:
+ case NODE_TYPEALIAS:
+ case NODE_TYPE_SPECIFIER:
+ case NODE_POINTER:
+ case NODE_TYPE_DECLARATOR:
+ case NODE_ENUMERATOR:
+ case NODE_ENUM:
+ case NODE_STRUCT_OR_VARIANT_DECLARATION:
+ case NODE_UNARY_EXPRESSION:
+ return -EPERM;
+
+ case NODE_UNKNOWN:
+ default:
+ fprintf(stderr, "[error] %s: unknown node type %d\n", __func__,
+ (int) parent->type);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int reparent_typealias(struct ctf_node *node, struct ctf_node *parent)
+{
+ switch (parent->type) {
+ case NODE_ROOT:
+ _cds_list_splice_tail(&node->tmp_head, &parent->u.root.typealias);
+ break;
+ case NODE_EVENT:
+ _cds_list_splice_tail(&node->tmp_head, &parent->u.event.declaration_list);
+ break;
+ case NODE_STREAM:
+ _cds_list_splice_tail(&node->tmp_head, &parent->u.stream.declaration_list);
+ break;
+ case NODE_TRACE:
+ _cds_list_splice_tail(&node->tmp_head, &parent->u.trace.declaration_list);
+ break;
+ case NODE_VARIANT:
+ _cds_list_splice_tail(&node->tmp_head, &parent->u.variant.declaration_list);
+ break;
+ case NODE_STRUCT:
+ _cds_list_splice_tail(&node->tmp_head, &parent->u._struct.declaration_list);
+ break;
+
+ case NODE_FLOATING_POINT:
+ case NODE_INTEGER:
+ case NODE_STRING:
+ case NODE_CTF_EXPRESSION:
+ case NODE_TYPEDEF:
+ case NODE_TYPEALIAS_TARGET:
+ case NODE_TYPEALIAS_ALIAS:
+ case NODE_TYPEALIAS:
+ case NODE_TYPE_SPECIFIER:
+ case NODE_POINTER:
+ case NODE_TYPE_DECLARATOR:
+ case NODE_ENUMERATOR:
+ case NODE_ENUM:
+ case NODE_STRUCT_OR_VARIANT_DECLARATION:
+ case NODE_UNARY_EXPRESSION:
+ return -EPERM;
+
+ case NODE_UNKNOWN:
+ default:
+ fprintf(stderr, "[error] %s: unknown node type %d\n", __func__,
+ (int) parent->type);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int reparent_type_specifier(struct ctf_node *node,
+ struct ctf_node *parent)
+{
+ switch (parent->type) {
+ case NODE_ROOT:
+ _cds_list_splice_tail(&node->tmp_head, &parent->u.root.declaration_specifier);
+ break;
+ case NODE_EVENT:
+ _cds_list_splice_tail(&node->tmp_head, &parent->u.event.declaration_list);
+ break;
+ case NODE_STREAM:
+ _cds_list_splice_tail(&node->tmp_head, &parent->u.stream.declaration_list);
+ break;
+ case NODE_TRACE:
+ _cds_list_splice_tail(&node->tmp_head, &parent->u.trace.declaration_list);
+ break;
+ case NODE_VARIANT:
+ _cds_list_splice_tail(&node->tmp_head, &parent->u.variant.declaration_list);
+ break;
+ case NODE_STRUCT:
+ _cds_list_splice_tail(&node->tmp_head, &parent->u._struct.declaration_list);
+ break;
+ case NODE_TYPEDEF:
+ _cds_list_splice_tail(&node->tmp_head, &parent->u._typedef.declaration_specifier);
+ break;
+ case NODE_TYPEALIAS_TARGET:
+ _cds_list_splice_tail(&node->tmp_head, &parent->u.typealias_target.declaration_specifier);
+ break;
+ case NODE_TYPEALIAS_ALIAS:
+ _cds_list_splice_tail(&node->tmp_head, &parent->u.typealias_alias.declaration_specifier);
+ break;
+ case NODE_TYPE_DECLARATOR:
+ parent->u.type_declarator.type = TYPEDEC_NESTED;
+ parent->u.type_declarator.u.nested.length = node;
+ break;
+ case NODE_ENUM:
+ parent->u._enum.container_type = node;
+ break;
+ case NODE_STRUCT_OR_VARIANT_DECLARATION:
+ _cds_list_splice_tail(&node->tmp_head, &parent->u.struct_or_variant_declaration.declaration_specifier);
+ break;
+ case NODE_TYPEALIAS:
+ case NODE_FLOATING_POINT:
+ case NODE_INTEGER:
+ case NODE_STRING:
+ case NODE_CTF_EXPRESSION:
+ case NODE_TYPE_SPECIFIER:
+ case NODE_POINTER:
+ case NODE_ENUMERATOR:
+ case NODE_UNARY_EXPRESSION:
+ return -EPERM;
+
+ case NODE_UNKNOWN:
+ default:
+ fprintf(stderr, "[error] %s: unknown node type %d\n", __func__,
+ (int) parent->type);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int reparent_type_declarator(struct ctf_node *node,
+ struct ctf_node *parent)
+{
+ switch (parent->type) {
+ case NODE_TYPE_DECLARATOR:
+ parent->u.type_declarator.type = TYPEDEC_NESTED;
+ parent->u.type_declarator.u.nested.type_declarator = node;
+ break;
+ case NODE_STRUCT_OR_VARIANT_DECLARATION:
+ _cds_list_splice_tail(&node->tmp_head, &parent->u.struct_or_variant_declaration.type_declarators);
+ break;
+ case NODE_TYPEDEF:
+ _cds_list_splice_tail(&node->tmp_head, &parent->u._typedef.type_declarators);
+ break;
+ case NODE_TYPEALIAS_TARGET:
+ _cds_list_splice_tail(&node->tmp_head, &parent->u.typealias_target.type_declarators);
+ break;
+ case NODE_TYPEALIAS_ALIAS:
+ _cds_list_splice_tail(&node->tmp_head, &parent->u.typealias_alias.type_declarators);
+ break;
+
+ case NODE_ROOT:
+ case NODE_EVENT:
+ case NODE_STREAM:
+ case NODE_TRACE:
+ case NODE_VARIANT:
+ case NODE_STRUCT:
+ case NODE_TYPEALIAS:
+ case NODE_ENUM:
+ case NODE_FLOATING_POINT:
+ case NODE_INTEGER:
+ case NODE_STRING:
+ case NODE_CTF_EXPRESSION:
+ case NODE_TYPE_SPECIFIER:
+ case NODE_POINTER:
+ case NODE_ENUMERATOR:
+ case NODE_UNARY_EXPRESSION:
+ return -EPERM;
+
+ case NODE_UNKNOWN:
+ default:
+ fprintf(stderr, "[error] %s: unknown node type %d\n", __func__,
+ (int) parent->type);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+/*
+ * set_parent_node
+ *
+ * Link node to parent. Returns 0 on success, -EPERM if it is not permitted to
+ * create the link declared by the input, -ENOENT if node or parent is NULL,
+ * -EINVAL if there is an internal structure problem.
+ */
+static int set_parent_node(struct ctf_node *node,
+ struct ctf_node *parent)
+{
+ if (!node || !parent)
+ return -ENOENT;
+
+ /* Note: Linking to parent will be done only by an external visitor */
+
+ switch (node->type) {
+ case NODE_ROOT:
+ fprintf(stderr, "[error] %s: trying to reparent root node\n", __func__);
+ return -EINVAL;
+
+ case NODE_EVENT:
+ if (parent->type == NODE_ROOT) {
+ _cds_list_splice_tail(&node->tmp_head, &parent->u.root.event);
+ } else
+ return -EPERM;
+ break;
+ case NODE_STREAM:
+ if (parent->type == NODE_ROOT) {
+ _cds_list_splice_tail(&node->tmp_head, &parent->u.root.stream);
+ } else
+ return -EPERM;
+ break;
+ case NODE_TRACE:
+ if (parent->type == NODE_ROOT) {
+ _cds_list_splice_tail(&node->tmp_head, &parent->u.root.trace);
+ } else
+ return -EPERM;
+ break;
+
+ case NODE_CTF_EXPRESSION:
+ return reparent_ctf_expression(node, parent);
+ case NODE_UNARY_EXPRESSION:
+ if (parent->type == NODE_TYPE_DECLARATOR)
+ parent->u.type_declarator.bitfield_len = node;
+ else
+ return -EPERM;
+ break;
+
+ case NODE_TYPEDEF:
+ return reparent_typedef(node, parent);
+ case NODE_TYPEALIAS_TARGET:
+ if (parent->type == NODE_TYPEALIAS)
+ parent->u.typealias.target = node;
+ else
+ return -EINVAL;
+ case NODE_TYPEALIAS_ALIAS:
+ if (parent->type == NODE_TYPEALIAS)
+ parent->u.typealias.alias = node;
+ else
+ return -EINVAL;
+ case NODE_TYPEALIAS:
+ return reparent_typealias(node, parent);
+
+ case NODE_POINTER:
+ if (parent->type == NODE_TYPE_DECLARATOR) {
+ _cds_list_splice_tail(&node->tmp_head, &parent->u.type_declarator.pointers);
+ } else
+ return -EPERM;
+ break;
+ case NODE_TYPE_DECLARATOR:
+ return reparent_type_declarator(node, parent);
+
+ case NODE_TYPE_SPECIFIER:
+ case NODE_FLOATING_POINT:
+ case NODE_INTEGER:
+ case NODE_STRING:
+ case NODE_ENUM:
+ case NODE_VARIANT:
+ case NODE_STRUCT:
+ return reparent_type_specifier(node, parent);
+
+ case NODE_ENUMERATOR:
+ if (parent->type == NODE_ENUM) {
+ _cds_list_splice_tail(&node->tmp_head, &parent->u._enum.enumerator_list);
+ } else
+ return -EPERM;
+ break;
+ case NODE_STRUCT_OR_VARIANT_DECLARATION:
+ switch (parent->type) {
+ case NODE_STRUCT:
+ _cds_list_splice_tail(&node->tmp_head, &parent->u._struct.declaration_list);
+ break;
+ case NODE_VARIANT:
+ _cds_list_splice_tail(&node->tmp_head, &parent->u.variant.declaration_list);
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+
+ case NODE_UNKNOWN:
+ default:
+ fprintf(stderr, "[error] %s: unknown node type %d\n", __func__,
+ (int) parent->type);
+ return -EINVAL;
+ }
+ return 0;