// File: /workspace/github_c_makefile_star2_O1/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 0xc074
movq %rdi, %r14
xorl %esi, %esi
callq 0x27c8
leaq -0x30(%rbp), %r12
movq $0x0, (%r12)
movq %rax, %rdi
movq %r12, %rsi
callq 0x2805
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
setne %r13b
je 0xbf99
xorl %r12d, %r12d
movq (%r15,%r12,8), %rdi
movl (%rdi), %ecx
cmpl $0x4000, %ecx           # imm = 0x4000
je 0xbf46
cmpl $0x6, %ecx
jne 0xbf53
jmp 0xbf92
movl $0x1, %esi
callq 0x27c8
movq %rax, %rdi
callq 0xbc78
movq %rax, (%rbx,%r12,8)
movl (%rax), %eax
testb $0x1, %al
jne 0xc05e
btl $0x9, %eax
jb 0xc04d
testb $0x10, %al
jne 0xc03c
testb $0x20, %al
jne 0xc02b
incq %r12
movq -0x30(%rbp), %rax
cmpq %rax, %r12
setb %r13b
jb 0xbf31
jmp 0xbf99
decq %rax
movq %rax, -0x30(%rbp)
movl $0x1, %esi
movq %r14, %rdi
callq 0x27c8
movq %rax, %r15
movq %rax, %rdi
callq 0xbc78
movq %rax, %r14
movl (%rax), %eax
btl $0x9, %eax
jb 0xc09c
testb $0x10, %al
jne 0xc0a9
testb $0x20, %al
jne 0xc0b6
movq -0x30(%rbp), %r15
andb $0x1, %r13b
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 0xc015
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 0x2b13(%rip), %rsi      # 0xeb4d
jmp 0xc06d
movq (%r15,%r12,8), %rax
movq 0x8(%rax), %rdi
leaq 0x2ad7(%rip), %rsi      # 0xeb22
jmp 0xc06d
movq (%r15,%r12,8), %rax
movq 0x8(%rax), %rdi
leaq 0x2a96(%rip), %rsi      # 0xeaf2
jmp 0xc06d
movq (%r15,%r12,8), %rax
movq 0x8(%rax), %rdi
leaq 0x2a5b(%rip), %rsi      # 0xeac8
xorl %eax, %eax
callq 0x5011
leaq 0x1131(%rip), %rdi      # 0xd1ac
leaq 0x2918(%rip), %rsi      # 0xe99a
leaq 0x2a16(%rip), %rcx      # 0xea9f
leaq 0x2a25(%rip), %r8       # 0xeab5
movl $0x114, %edx            # imm = 0x114
xorl %eax, %eax
callq 0x4f1c
movq 0x8(%r15), %rdi
leaq 0x2ad4(%rip), %rsi      # 0xeb7b
jmp 0xc06d
movq 0x8(%r15), %rdi
leaq 0x2afa(%rip), %rsi      # 0xebae
jmp 0xc06d
movq 0x8(%r15), %rdi
leaq 0x2b1b(%rip), %rsi      # 0xebdc
jmp 0xc06d