Libclang with python binding to extract structure with unnamed field

Hello,

I am trying to extract structure declaration from GNU/Linux kernel, basically this is the code I’m using for it (compiler arguments came from kernel compilation):

#!/usr/bin/env python3

import os
import pathlib
import shlex
import clang.cindex


CLANG_ARGS='-Wp,-MMD,drivers/scsi/aic7xxx/.aic79xx_osm.o.d -nostdinc -I./arch/x86/include -I./arch/x86/include/generated  -I./include -I./arch/x86/include/uapi -I./arch/x86/include/generated/uapi -I./include/uapi -I./include/generated/uapi -include ./include/linux/compiler-version.h -include ./include/linux/kconfig.h -include ./include/linux/compiler_types.h -D__KERNEL__ -fmacro-prefix-map=./= -Wall -Wundef -Werror=strict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -fshort-wchar -fno-PIE -Werror=implicit-function-declaration -Werror=implicit-int -Werror=return-type -Wno-format-security -std=gnu11 -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -fcf-protection=none -m64 -mno-80387 -mtune=generic -mno-red-zone -mcmodel=kernel -Wno-sign-compare -fno-asynchronous-unwind-tables -fno-jump-tables -fno-delete-null-pointer-checks -Wno-frame-address -Wno-address-of-packed-member -Wno-gnu-variable-sized-type-not-at-end -O2 -fstack-protector-strong -Wno-main -Wno-unused-but-set-variable -Wno-unused-const-variable -fno-stack-clash-protection -pg -mfentry -DCC_USING_FENTRY -Wdeclaration-after-statement -Wvla -Wno-pointer-sign -Wcast-function-type -Wno-array-bounds -Wimplicit-fallthrough -fno-strict-overflow -fno-stack-check -Werror=date-time -Werror=incompatible-pointer-types -DKBUILD_MODFILE="drivers/scsi/aic7xxx/aic79xx" -DKBUILD_BASENAME="aic79xx_osm" -DKBUILD_MODNAME="aic79xx" -D__KBUILD_MODNAME=kmod_aic79xx'

def extract_structure(cursor):

    print("{} {{".format(cursor.type.spelling))
    for field in cursor.type.get_fields():
        print("\t{} {};".format(field.type.spelling, field.spelling))

    print("};\n---\n")

def main(filepath):

    index  = clang.cindex.Index.create()
    tu     = index.parse(filepath,
                         options=clang.cindex.TranslationUnit.PARSE_DETAILED_PROCESSING_RECORD,
                         args=shlex.split(CLANG_ARGS))
    cursor = tu.cursor

    for diag in tu.diagnostics:
        print("[*] diagnotics: {}".format(diag))

    for child in cursor.get_children():
        if child.kind == clang.cindex.CursorKind.STRUCT_DECL:
            extract_structure(child)


if __name__ == '__main__':

    cwd = pathlib.Path.cwd()

    os.chdir("/usr/src/linux-6.1.6")
    main("./drivers/scsi/aic7xxx/aic79xx_osm.c")
    os.chdir(cwd)

My issue is the unnamed structure and anonymous union. For example, for the file parsed (aic79xx_osm.c), it produces this structure (first one in ./drivers/scsi/aic7xxx/aic79xx_osm.h):

struct ahd_linux_device {
        struct (unnamed struct at ./drivers/scsi/aic7xxx/aic79xx_osm.h:236:2) links;
        int active;
        int openings;
        u_int qfrozen;
        u_long commands_issued;
        u_int tag_success_count;
        ahd_linux_dev_flags flags;
        struct timer_list timer;
        u_int maxtags;
        u_int tags_on_last_queuefull;
        u_int last_queuefull_same_count;
        u_int commands_since_idle_or_otag;
};

The original structure is that one below (comments removed):

struct ahd_linux_device {
        TAILQ_ENTRY(ahd_linux_device) links;
        int                     active;
        int                     openings;
        u_int                   qfrozen;
        u_long                  commands_issued;
        u_int                   tag_success_count;
#define AHD_TAG_SUCCESS_INTERVAL 50
        ahd_linux_dev_flags     flags;
        struct timer_list       timer;
        u_int                   maxtags;
        u_int                   tags_on_last_queuefull;
        u_int                   last_queuefull_same_count;
#define AHD_LOCK_TAGS_COUNT 50
        u_int                   commands_since_idle_or_otag;
#define AHD_OTAG_THRESH 500
};

TAILQ_ENTRY is defined in ./drivers/scsi/aic7xxx/queue.h as below:

#define TAILQ_ENTRY(type)                                               \
struct {                                                                \
        struct type *tqe_next;  /* next element */                      \
        struct type **tqe_prev; /* address of previous next element */  \
}

So ideally I would like this result:

struct ahd_linux_device {
        struct {
            struct ahd_linux_device * tqe_next;
            struct ahd_linux_device ** tqe_prev;
        } links;
        int                     active;
        int                     openings;
[...]
};

Or if I can keep TAILQ_ENTRY its still fine. But I have no idea of how I can achieved this. Is there way to do it ?