// File: /workspace/github_c_makefile_star2_O0/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
subq $0x60, %rsp
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
cmpl $0x4302, (%rax)         # imm = 0x4302
je 0x107f0
leaq 0x1835(%rip), %rdi      # 0x12004
leaq 0x3f68(%rip), %rsi      # 0x1473e
movl $0x114, %edx            # imm = 0x114
leaq 0x40b3(%rip), %rcx      # 0x14895
leaq 0x40c2(%rip), %r8       # 0x148ab
movb $0x0, %al
callq 0x6510
movq -0x8(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x2a40
movq %rax, -0x10(%rbp)
movq $0x0, -0x18(%rbp)
movq -0x10(%rbp), %rdi
leaq -0x18(%rbp), %rsi
callq 0x2ad0
movq %rax, -0x20(%rbp)
movq -0x18(%rbp), %rax
movq %rsp, %rcx
movq %rcx, -0x28(%rbp)
leaq 0xf(,%rax,8), %rdx
andq $-0x10, %rdx
movq %rsp, %rcx
subq %rdx, %rcx
movq %rcx, -0x58(%rbp)
movq %rcx, %rsp
movq %rax, -0x30(%rbp)
movb $0x0, -0x31(%rbp)
movq $0x0, -0x40(%rbp)
movq -0x40(%rbp), %rax
cmpq -0x18(%rbp), %rax
jae 0x109ce
movq -0x20(%rbp), %rax
movq -0x40(%rbp), %rcx
movq (%rax,%rcx,8), %rax
cmpl $0x4000, (%rax)         # imm = 0x4000
jne 0x1089f
movq -0x20(%rbp), %rax
movq -0x40(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
movl $0x1, %esi
callq 0x2a40
movq %rax, %rdi
callq 0x10600
movq %rax, %rdx
movq -0x58(%rbp), %rax
movq -0x40(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
jmp 0x108e7
movq -0x20(%rbp), %rax
movq -0x40(%rbp), %rcx
movq (%rax,%rcx,8), %rax
cmpl $0x6, (%rax)
jne 0x108c5
movb $0x1, -0x31(%rbp)
movq -0x18(%rbp), %rax
addq $-0x1, %rax
movq %rax, -0x18(%rbp)
jmp 0x109ce
movq -0x20(%rbp), %rax
movq -0x40(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x10600
movq %rax, %rdx
movq -0x58(%rbp), %rax
movq -0x40(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
jmp 0x108e7
movq -0x58(%rbp), %rax
movq -0x40(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x113b0
testb $0x1, %al
jne 0x108fe
jmp 0x1091c
movq -0x20(%rbp), %rax
movq -0x40(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq 0x8(%rax), %rdi
leaq 0x3fa9(%rip), %rsi      # 0x148be
movb $0x0, %al
callq 0x6610
movq -0x58(%rbp), %rax
movq -0x40(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x113d0
testb $0x1, %al
jne 0x10933
jmp 0x10951
movq -0x20(%rbp), %rax
movq -0x40(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq 0x8(%rax), %rdi
leaq 0x3f9e(%rip), %rsi      # 0x148e8
movb $0x0, %al
callq 0x6610
movq -0x58(%rbp), %rax
movq -0x40(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x104e0
testb $0x1, %al
jne 0x10968
jmp 0x10986
movq -0x20(%rbp), %rax
movq -0x40(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq 0x8(%rax), %rdi
leaq 0x3f99(%rip), %rsi      # 0x14918
movb $0x0, %al
callq 0x6610
movq -0x58(%rbp), %rax
movq -0x40(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x10550
testb $0x1, %al
jne 0x1099d
jmp 0x109bb
movq -0x20(%rbp), %rax
movq -0x40(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq 0x8(%rax), %rdi
leaq 0x3f8f(%rip), %rsi      # 0x14943
movb $0x0, %al
callq 0x6610
jmp 0x109bd
movq -0x40(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x40(%rbp)
jmp 0x1084e
movq -0x8(%rbp), %rdi
movl $0x1, %esi
callq 0x2a40
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rdi
callq 0x10600
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rdi
callq 0x113d0
testb $0x1, %al
jne 0x109fc
jmp 0x10a12
movq -0x48(%rbp), %rax
movq 0x8(%rax), %rdi
leaq 0x3f66(%rip), %rsi      # 0x14971
movb $0x0, %al
callq 0x6610
movq -0x50(%rbp), %rdi
callq 0x104e0
testb $0x1, %al
jne 0x10a21
jmp 0x10a37
movq -0x48(%rbp), %rax
movq 0x8(%rax), %rdi
leaq 0x3f74(%rip), %rsi      # 0x149a4
movb $0x0, %al
callq 0x6610
movq -0x50(%rbp), %rdi
callq 0x10550
testb $0x1, %al
jne 0x10a46
jmp 0x10a5c
movq -0x48(%rbp), %rax
movq 0x8(%rax), %rdi
leaq 0x3f7d(%rip), %rsi      # 0x149d2
movb $0x0, %al
callq 0x6610
movq -0x58(%rbp), %rdx
movq -0x50(%rbp), %rdi
movq -0x18(%rbp), %rsi
movb -0x31(%rbp), %al
andb $0x1, %al
movzbl %al, %ecx
callq 0x10250
movq -0x28(%rbp), %rcx
movq %rcx, %rsp
movq %rbp, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)