// File: /workspace/github_c_makefile_star2_O3/lucvoo[P]sparse-dev/evaluate.c
// Function: evaluate_call
static struct symbol *evaluate_call(struct expression *expr)
{
	int args, fnargs;
	struct symbol *ctype, *sym;
	struct expression *fn = expr->fn;
	struct expression_list *arglist = expr->args;

	if (!evaluate_expression(fn))
		return NULL;
	sym = ctype = fn->ctype;
	if (ctype->type == SYM_NODE)
		ctype = ctype->ctype.base_type;
	if (ctype->type == SYM_PTR)
		ctype = get_base_type(ctype);

	if (ctype->type != SYM_FN) {
		struct expression *arg;

		if (fn->ctype == &bad_ctype)
			return NULL;

		expression_error(expr, "not a function %s",
			     show_ident(sym->ident));
		/* do typechecking in arguments */
		FOR_EACH_PTR (arglist, arg) {
			evaluate_expression(arg);
		} END_FOR_EACH_PTR(arg);
		return NULL;
	}

	examine_fn_arguments(ctype);
        if (sym->type == SYM_NODE && fn->type == EXPR_PREOP &&
	    sym->op && sym->op->args) {
		if (!sym->op->args(expr))
			return NULL;
	} else {
		if (!evaluate_arguments(ctype->arguments, arglist))
			return NULL;
		args = expression_list_size(expr->args);
		fnargs = symbol_list_size(ctype->arguments);
		if (args < fnargs) {
			expression_error(expr,
				     "not enough arguments for function %s",
				     show_ident(sym->ident));
			return NULL;
		}
		if (args > fnargs && !ctype->variadic)
			expression_error(expr,
				     "too many arguments for function %s",
				     show_ident(sym->ident));
	}
	expr->ctype = ctype->ctype.base_type;
	if (sym->type == SYM_NODE) {
		if (evaluate_symbol_call(expr))
			return expr->ctype;
	}
	return expr->ctype;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rdi, %rbx
movq 0x20(%rdi), %r12
movq 0x28(%rdi), %r14
movq %r12, %rdi
callq 0x32223
testq %rax, %rax
je 0x34f89
movq 0x10(%r12), %r13
movzbl (%r13), %eax
movq %r13, %r15
cmpl $0x3, %eax
jne 0x34e54
movq 0x60(%r13), %r15
movzbl (%r15), %eax
cmpl $0x4, %eax
jne 0x34e68
movq 0x60(%r15), %rdi
callq 0x2b0b8
movq %rax, %r15
movzbl (%rax), %eax
cmpl $0x5, %eax
jne 0x34eb7
movq %r15, %rdi
callq 0x31d66
cmpb $0x3, (%r13)
jne 0x34f39
cmpb $0x9, (%r12)
jne 0x34f39
movq 0x40(%r13), %rax
testq %rax, %rax
je 0x34f39
movq 0x18(%rax), %rax
testq %rax, %rax
je 0x34f39
movq %rbx, %rdi
callq *%rax
testl %eax, %eax
jne 0x34fc4
jmp 0x34f89
movq 0x10(%r12), %rax
cmpq 0x2b09d(%rip), %rax     # 0x5ff60
je 0x34f89
movq 0x18(%r13), %rdi
callq 0x2de35
leaq 0x1567e(%rip), %rsi     # 0x4a557
xorl %r15d, %r15d
movq %rbx, %rdi
movq %rax, %rdx
xorl %eax, %eax
callq 0x11b04
testq %r14, %r14
je 0x34f8c
xorl %r15d, %r15d
movq %r14, %rbx
movzwl (%rbx), %eax
testb %al, %al
jle 0x34f2e
xorl %r12d, %r12d
movq 0x18(%rbx,%r12,8), %rdi
movzwl %ax, %ecx
cmpl $0x100, %ecx            # imm = 0x100
jb 0x34f17
testq %rdi, %rdi
je 0x34f1f
callq 0x32223
movzwl (%rbx), %eax
incq %r12
movzwl %ax, %ecx
movsbq %cl, %rcx
cmpq %rcx, %r12
jl 0x34f02
movq 0x10(%rbx), %rbx
cmpq %r14, %rbx
jne 0x34ef8
jmp 0x34f8c
movq 0x88(%r15), %rdi
movq %r14, %rsi
callq 0x31eba
testl %eax, %eax
je 0x34f89
movq 0x28(%rbx), %rdi
callq 0x22530
movl %eax, %ebp
movq 0x88(%r15), %rdi
callq 0x22530
cmpl %eax, %ebp
jge 0x34f9e
movq 0x18(%r13), %rdi
callq 0x2de35
leaq 0x155f2(%rip), %rsi     # 0x4a569
xorl %r15d, %r15d
movq %rbx, %rdi
movq %rax, %rdx
xorl %eax, %eax
callq 0x11b04
jmp 0x34f8c
xorl %r15d, %r15d
movq %r15, %rax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jle 0x34fc4
testb $0x2, 0x55(%r15)
jne 0x34fc4
movq 0x18(%r13), %rdi
callq 0x2de35
leaq 0x155d7(%rip), %rsi     # 0x4a58e
movq %rbx, %rdi
movq %rax, %rdx
xorl %eax, %eax
callq 0x11b04
movq 0x60(%r15), %r15
movq %r15, 0x10(%rbx)
cmpb $0x3, (%r13)
jne 0x34f8c
movq 0x20(%rbx), %rax
cmpb $0x9, (%rax)
jne 0x34f8c
movq 0x10(%rax), %rax
movq 0x40(%rax), %rax
testq %rax, %rax
je 0x34f8c
movq 0x8(%rax), %rax
testq %rax, %rax
je 0x34f8c
movq %rbx, %rdi
callq *%rax
movq 0x10(%rbx), %r15
jmp 0x34f8c