+
+ /* Pass it as content of outer container */
+ declaration = ctf_type_declarator_visit(fd, depth,
+ type_specifier_list, field_name,
+ node_type_declarator->u.type_declarator.u.nested.type_declarator,
+ declaration_scope, declaration, trace);
+ return declaration;
+ }
+}
+
+static
+int ctf_struct_type_declarators_visit(FILE *fd, int depth,
+ struct declaration_struct *struct_declaration,
+ struct ctf_node *type_specifier_list,
+ struct cds_list_head *type_declarators,
+ struct declaration_scope *declaration_scope,
+ struct ctf_trace *trace)
+{
+ struct ctf_node *iter;
+ GQuark field_name;
+
+ cds_list_for_each_entry(iter, type_declarators, siblings) {
+ struct declaration *field_declaration;
+
+ field_declaration = ctf_type_declarator_visit(fd, depth,
+ type_specifier_list,
+ &field_name, iter,
+ struct_declaration->scope,
+ NULL, trace);
+ if (!field_declaration) {
+ fprintf(fd, "[error] %s: unable to find struct field declaration type\n", __func__);
+ return -EINVAL;
+ }
+ struct_declaration_add_field(struct_declaration,
+ g_quark_to_string(field_name),
+ field_declaration);
+ }
+ return 0;
+}
+
+static
+int ctf_variant_type_declarators_visit(FILE *fd, int depth,
+ struct declaration_untagged_variant *untagged_variant_declaration,
+ struct ctf_node *type_specifier_list,
+ struct cds_list_head *type_declarators,
+ struct declaration_scope *declaration_scope,
+ struct ctf_trace *trace)
+{
+ struct ctf_node *iter;
+ GQuark field_name;
+
+ cds_list_for_each_entry(iter, type_declarators, siblings) {
+ struct declaration *field_declaration;
+
+ field_declaration = ctf_type_declarator_visit(fd, depth,
+ type_specifier_list,
+ &field_name, iter,
+ untagged_variant_declaration->scope,
+ NULL, trace);
+ if (!field_declaration) {
+ fprintf(fd, "[error] %s: unable to find variant field declaration type\n", __func__);
+ return -EINVAL;
+ }
+ untagged_variant_declaration_add_field(untagged_variant_declaration,
+ g_quark_to_string(field_name),
+ field_declaration);
+ }
+ return 0;
+}
+
+static
+int ctf_typedef_visit(FILE *fd, int depth, struct declaration_scope *scope,
+ struct ctf_node *type_specifier_list,
+ struct cds_list_head *type_declarators,
+ struct ctf_trace *trace)
+{
+ struct ctf_node *iter;
+ GQuark identifier;
+
+ cds_list_for_each_entry(iter, type_declarators, siblings) {
+ struct declaration *type_declaration;
+ int ret;
+
+ type_declaration = ctf_type_declarator_visit(fd, depth,
+ type_specifier_list,
+ &identifier, iter,
+ scope, NULL, trace);
+ if (!type_declaration) {
+ fprintf(fd, "[error] %s: problem creating type declaration\n", __func__);
+ return -EINVAL;
+ }
+ /*
+ * Don't allow typedef and typealias of untagged
+ * variants.
+ */
+ if (type_declaration->id == CTF_TYPE_UNTAGGED_VARIANT) {
+ fprintf(fd, "[error] %s: typedef of untagged variant is not permitted.\n", __func__);
+ declaration_unref(type_declaration);
+ return -EPERM;
+ }
+ ret = register_declaration(identifier, type_declaration, scope);
+ if (ret) {
+ type_declaration->declaration_free(type_declaration);
+ return ret;
+ }
+ }
+ return 0;
+}
+
+static
+int ctf_typealias_visit(FILE *fd, int depth, struct declaration_scope *scope,
+ struct ctf_node *target, struct ctf_node *alias,
+ struct ctf_trace *trace)
+{
+ struct declaration *type_declaration;
+ struct ctf_node *node;
+ GQuark dummy_id;
+ GQuark alias_q;
+ int err;
+
+ /* See ctf_visitor_type_declarator() in the semantic validator. */
+
+ /*
+ * Create target type declaration.
+ */
+
+ if (cds_list_empty(&target->u.typealias_target.type_declarators))
+ node = NULL;
+ else
+ node = _cds_list_first_entry(&target->u.typealias_target.type_declarators,
+ struct ctf_node, siblings);
+ type_declaration = ctf_type_declarator_visit(fd, depth,
+ target->u.typealias_target.type_specifier_list,
+ &dummy_id, node,
+ scope, NULL, trace);
+ if (!type_declaration) {
+ fprintf(fd, "[error] %s: problem creating type declaration\n", __func__);
+ err = -EINVAL;
+ goto error;
+ }
+ /*
+ * Don't allow typedef and typealias of untagged
+ * variants.
+ */
+ if (type_declaration->id == CTF_TYPE_UNTAGGED_VARIANT) {
+ fprintf(fd, "[error] %s: typedef of untagged variant is not permitted.\n", __func__);
+ declaration_unref(type_declaration);
+ return -EPERM;
+ }
+ /*
+ * The semantic validator does not check whether the target is
+ * abstract or not (if it has an identifier). Check it here.
+ */
+ if (dummy_id != 0) {
+ fprintf(fd, "[error] %s: expecting empty identifier\n", __func__);
+ err = -EINVAL;
+ goto error;
+ }
+ /*
+ * Create alias identifier.
+ */
+
+ node = _cds_list_first_entry(&alias->u.typealias_alias.type_declarators,
+ struct ctf_node, siblings);
+ alias_q = create_typealias_identifier(fd, depth,
+ alias->u.typealias_alias.type_specifier_list, node);
+ err = register_declaration(alias_q, type_declaration, scope);
+ if (err)
+ goto error;
+ return 0;
+
+error:
+ type_declaration->declaration_free(type_declaration);
+ return err;
+}
+
+static
+int ctf_struct_declaration_list_visit(FILE *fd, int depth,
+ struct ctf_node *iter, struct declaration_struct *struct_declaration,
+ struct ctf_trace *trace)
+{
+ int ret;
+
+ switch (iter->type) {
+ case NODE_TYPEDEF:
+ /* For each declarator, declare type and add type to struct declaration scope */
+ ret = ctf_typedef_visit(fd, depth,
+ struct_declaration->scope,
+ iter->u._typedef.type_specifier_list,
+ &iter->u._typedef.type_declarators, trace);
+ if (ret)
+ return ret;
+ break;
+ case NODE_TYPEALIAS:
+ /* Declare type with declarator and add type to struct declaration scope */
+ ret = ctf_typealias_visit(fd, depth,
+ struct_declaration->scope,
+ iter->u.typealias.target,
+ iter->u.typealias.alias, trace);
+ if (ret)
+ return ret;
+ break;
+ case NODE_STRUCT_OR_VARIANT_DECLARATION:
+ /* Add field to structure declaration */
+ ret = ctf_struct_type_declarators_visit(fd, depth,
+ struct_declaration,
+ iter->u.struct_or_variant_declaration.type_specifier_list,
+ &iter->u.struct_or_variant_declaration.type_declarators,
+ struct_declaration->scope, trace);
+ if (ret)
+ return ret;