// File: /workspace/github_c_makefile_star2_O3/ryvnf[P]czc/type.c
// Function: type_from_func_ast
static struct type *type_from_func_ast(struct ast *ast)
{
    assert(ast->tag == FUNC_EXPR);

    struct ast *param_list = ast_ast(ast, 0);

    size_t n_params = 0;
    struct ast **param_asts = ast_asts(param_list, &n_params);

    struct type *param_types[n_params];
    bool is_vararg = false;

    for (size_t i = 0; i < n_params; i++) {
        if (param_asts[i]->tag == DECL) {
            param_types[i] = type_from_ast(ast_ast(param_asts[i], 1));
        } else if (param_asts[i]->tag == VARARG_TYPE) {
            is_vararg = true;
            n_params--;
            break;
        } else {
            param_types[i] = type_from_ast(param_asts[i]);
        }

        if (is_void_type(param_types[i]))
            fatal(param_asts[i]->loc, "function parameter cannot be of void type");

        if (is_extern_type(param_types[i]))
            fatal(param_asts[i]->loc, "function parameter cannot be of incomplete type");

        if (is_array_type(param_types[i]))
            fatal(param_asts[i]->loc, "function parameter cannot be of array type");

        if (is_func_type(param_types[i]))
            fatal(param_asts[i]->loc, "function parameter cannot be of function type");
    }

    struct ast *ret_ast = ast_ast(ast, 1);
    struct type *ret_type = type_from_ast(ret_ast);

    if (is_extern_type(ret_type))
        fatal(ret_ast->loc, "function return value cannot be of incomplete type");

    if (is_array_type(ret_type))
        fatal(ret_ast->loc, "function return value cannot be of array type");

    if (is_func_type(ret_type))
        fatal(ret_ast->loc, "function return value cannot be of function type");

    return new_func_type(ret_type, n_params, param_types, is_vararg);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
cmpl $0x4302, (%rdi)         # imm = 0x4302
jne 0xbe04
movq %rdi, %r14
xorl %r13d, %r13d
xorl %esi, %esi
callq 0x27e8
leaq -0x30(%rbp), %r12
movq $0x0, (%r12)
movq %rax, %rdi
movq %r12, %rsi
callq 0x2825
movq %rax, %r15
movq %rsp, -0x38(%rbp)
movq (%r12), %rax
movq %rsp, %rbx
leaq 0xf(,%rax,8), %rax
andq $-0x10, %rax
subq %rax, %rbx
movq %rbx, %rsp
movq (%r12), %rax
testq %rax, %rax
je 0xbd2d
xorl %r12d, %r12d
movq (%r15,%r12,8), %rdi
movl (%rdi), %ecx
cmpl $0x4000, %ecx           # imm = 0x4000
je 0xbcd8
cmpl $0x6, %ecx
jne 0xbce5
jmp 0xbd23
movl $0x1, %esi
callq 0x27e8
movq %rax, %rdi
callq 0xba08
movq %rax, (%rbx,%r12,8)
movl (%rax), %eax
testb $0x1, %al
jne 0xbdee
btl $0x9, %eax
jb 0xbddd
testb $0x10, %al
jne 0xbdcc
testb $0x20, %al
jne 0xbdbb
incq %r12
movq -0x30(%rbp), %rax
cmpq %rax, %r12
jb 0xbcc3
xorl %r13d, %r13d
jmp 0xbd2d
decq %rax
movq %rax, -0x30(%rbp)
movb $0x1, %r13b
movl $0x1, %esi
movq %r14, %rdi
callq 0x27e8
movq %rax, %r15
movq %rax, %rdi
callq 0xba08
movq %rax, %r14
movl (%rax), %eax
btl $0x9, %eax
jb 0xbe2c
testb $0x10, %al
jne 0xbe39
testb $0x20, %al
jne 0xbe46
movq -0x30(%rbp), %r15
leaq 0x20(,%r15,8), %rdi
callq 0x2160
movq %rax, %r12
movl $0x20, (%rax)
movq %r14, 0x8(%rax)
movq %r15, 0x10(%rax)
movb %r13b, 0x18(%rax)
testq %r15, %r15
je 0xbda5
shlq $0x3, %r15
movq %r12, %rdi
addq $0x20, %rdi
movq %rbx, %rsi
movq %r15, %rdx
callq 0x2150
movq -0x38(%rbp), %rsp
movq %r12, %rax
leaq -0x28(%rbp), %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq (%r15,%r12,8), %rax
movq 0x8(%rax), %rdi
leaq 0x2d73(%rip), %rsi      # 0xeb3d
jmp 0xbdfd
movq (%r15,%r12,8), %rax
movq 0x8(%rax), %rdi
leaq 0x2d37(%rip), %rsi      # 0xeb12
jmp 0xbdfd
movq (%r15,%r12,8), %rax
movq 0x8(%rax), %rdi
leaq 0x2cf6(%rip), %rsi      # 0xeae2
jmp 0xbdfd
movq (%r15,%r12,8), %rax
movq 0x8(%rax), %rdi
leaq 0x2cbb(%rip), %rsi      # 0xeab8
xorl %eax, %eax
callq 0x4fa1
leaq 0x13a1(%rip), %rdi      # 0xd1ac
leaq 0x2b78(%rip), %rsi      # 0xe98a
leaq 0x2c76(%rip), %rcx      # 0xea8f
leaq 0x2c85(%rip), %r8       # 0xeaa5
movl $0x114, %edx            # imm = 0x114
xorl %eax, %eax
callq 0x4eac
movq 0x8(%r15), %rdi
leaq 0x2d34(%rip), %rsi      # 0xeb6b
jmp 0xbdfd
movq 0x8(%r15), %rdi
leaq 0x2d5a(%rip), %rsi      # 0xeb9e
jmp 0xbdfd
movq 0x8(%r15), %rdi
leaq 0x2d7b(%rip), %rsi      # 0xebcc
jmp 0xbdfd