// File: /workspace/github_c_makefile_star2_O1/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 0x32c63
testq %rax, %rax
je 0x359b4
movq 0x10(%r12), %r13
cmpb $0x3, (%r13)
movq %r13, %r15
jne 0x35885
movq 0x60(%r13), %r15
cmpb $0x4, (%r15)
jne 0x35897
movq 0x60(%r15), %rdi
callq 0x2b5f4
movq %rax, %r15
cmpb $0x5, (%r15)
jne 0x358e7
movq %r15, %rdi
callq 0x32794
cmpb $0x3, (%r13)
jne 0x35964
cmpb $0x9, (%r12)
jne 0x35964
movq 0x40(%r13), %rax
testq %rax, %rax
je 0x35964
movq 0x18(%rax), %rax
testq %rax, %rax
je 0x35964
movq %rbx, %rdi
callq *%rax
testl %eax, %eax
jne 0x359ef
jmp 0x359b4
movq 0x10(%r12), %rax
cmpq 0x2b65d(%rip), %rax     # 0x60f50
je 0x359b4
movq 0x18(%r13), %rdi
callq 0x2e465
leaq 0x15cde(%rip), %rsi     # 0x4b5e7
xorl %r15d, %r15d
movq %rbx, %rdi
movq %rax, %rdx
xorl %eax, %eax
callq 0x11abc
testq %r14, %r14
je 0x359b7
xorl %r15d, %r15d
movq %r14, %rbx
movzwl (%rbx), %eax
testb %al, %al
jle 0x35959
xorl %r12d, %r12d
movq 0x18(%rbx,%r12,8), %rdi
movzwl %ax, %eax
cmpl $0x100, %eax            # imm = 0x100
jb 0x35946
testq %rdi, %rdi
je 0x3594b
callq 0x32c63
incq %r12
movl (%rbx), %eax
movsbq %al, %rcx
cmpq %rcx, %r12
jl 0x35932
movq 0x10(%rbx), %rbx
cmpq %r14, %rbx
jne 0x35928
jmp 0x359b7
movq 0x88(%r15), %rdi
movq %r14, %rsi
callq 0x328e8
testl %eax, %eax
je 0x359b4
movq 0x28(%rbx), %rdi
callq 0x225b4
movl %eax, %ebp
movq 0x88(%r15), %rdi
callq 0x225b4
cmpl %eax, %ebp
jge 0x359c9
movq 0x18(%r13), %rdi
callq 0x2e465
leaq 0x15c57(%rip), %rsi     # 0x4b5f9
xorl %r15d, %r15d
movq %rbx, %rdi
movq %rax, %rdx
xorl %eax, %eax
callq 0x11abc
jmp 0x359b7
xorl %r15d, %r15d
movq %r15, %rax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jle 0x359ef
testb $0x2, 0x55(%r15)
jne 0x359ef
movq 0x18(%r13), %rdi
callq 0x2e465
leaq 0x15c3c(%rip), %rsi     # 0x4b61e
movq %rbx, %rdi
movq %rax, %rdx
xorl %eax, %eax
callq 0x11abc
movq 0x60(%r15), %rax
movq %rax, 0x10(%rbx)
cmpb $0x3, (%r13)
jne 0x35a24
movq 0x20(%rbx), %rax
cmpb $0x9, (%rax)
jne 0x35a24
movq 0x10(%rax), %rax
movq 0x40(%rax), %rax
testq %rax, %rax
je 0x35a24
movq 0x8(%rax), %rax
testq %rax, %rax
je 0x35a24
movq %rbx, %rdi
callq *%rax
testl %eax, %eax
movq 0x10(%rbx), %r15
jmp 0x359b7