// File: /workspace/github_c_makefile_star2_O0/Mithreindeir[P]ewcc/src/frontend/cdecl.c
// Function: parse_function
struct stmt *parse_function(struct parser *p)
{
	enum type_specifier dtype = type_int;
	if (match(p, t_void)) dtype=type_void;
	else if (match(p, t_int))  dtype = type_int;
	else if (match(p, t_char)) dtype = type_char;
	else printf("Warning: return type defaults to int\n");
	/*Validify function declaration, then parse body */
	struct declaration *decl;
	decl = malloc(sizeof(struct declaration));
	decl->initializer = NULL;
	decl->ident = NULL;
	decl->type = NULL;
	if (!parse_declarator(p, decl)) {
		free(decl);
		return 0;
	}
	if (!decl->type) syntax_error(p, "Invalid declarator");
	/*The type must be a function */
	if (decl->type->type != type_fcn) {
		free(decl->ident);
		type_free(decl->type);
		free(decl);
		return 0;
	}

	struct type *decldtype = type_init(type_datatype);
	decldtype->info.data_type = dtype;
	decl->type = types_merge(decl->type, decldtype);
	set_type(get_scope(p), decl->ident, decl->type);
	/*Create function from declaration */
	struct stmt *block;
	if (!(block = parse_block(p))) {
		free(decl->ident);
		type_free(decl->type);
		free(decl);
		return 0;
	}
	struct stmt *fn = func_init(decl->ident, decl->type, block);
	free(decl);
	struct type *ftype = FUNC(fn)->ftype;
	/*lastly, add parameters to block scope */
	for (int i = 0; i < ftype->info.fcn.paramc; i++) {
		char *pn = ftype->info.fcn.paramv[i];
		struct type *pt = ftype->info.fcn.paramt[i];
		set_type(BLOCK(FUNC(fn)->body)->scope, pn, pt);
	}

	return fn;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x10(%rbp)
movl $0x1, -0x14(%rbp)
movq -0x10(%rbp), %rdi
movl $0x3, %esi
callq 0xaab0
cmpq $0x0, %rax
je 0x8590
movl $0x0, -0x14(%rbp)
jmp 0x85dc
movq -0x10(%rbp), %rdi
movl $0x4, %esi
callq 0xaab0
cmpq $0x0, %rax
je 0x85ad
movl $0x1, -0x14(%rbp)
jmp 0x85da
movq -0x10(%rbp), %rdi
movl $0x5, %esi
callq 0xaab0
cmpq $0x0, %rax
je 0x85ca
movl $0x2, -0x14(%rbp)
jmp 0x85d8
leaq 0x40a5(%rip), %rdi      # 0xc676
movb $0x0, %al
callq 0x2060
jmp 0x85da
jmp 0x85dc
movl $0x18, %edi
callq 0x20e0
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
movq $0x0, 0x10(%rax)
movq -0x20(%rbp), %rax
movq $0x0, (%rax)
movq -0x20(%rbp), %rax
movq $0x0, 0x8(%rax)
movq -0x10(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x8240
cmpl $0x0, %eax
jne 0x8635
movq -0x20(%rbp), %rdi
callq 0x2030
movq $0x0, -0x8(%rbp)
jmp 0x87c2
movq -0x20(%rbp), %rax
cmpq $0x0, 0x8(%rax)
jne 0x8650
movq -0x10(%rbp), %rdi
leaq 0x4051(%rip), %rsi      # 0xc69c
callq 0xabb0
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rax
cmpl $0x3, 0x18(%rax)
je 0x868d
movq -0x20(%rbp), %rax
movq (%rax), %rdi
callq 0x2030
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rdi
callq 0xb150
movq -0x20(%rbp), %rdi
callq 0x2030
movq $0x0, -0x8(%rbp)
jmp 0x87c2
xorl %edi, %edi
callq 0xb0a0
movq %rax, -0x28(%rbp)
movl -0x14(%rbp), %ecx
movq -0x28(%rbp), %rax
movl %ecx, (%rax)
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rdi
movq -0x28(%rbp), %rsi
callq 0xb0e0
movq %rax, %rcx
movq -0x20(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x10(%rbp), %rdi
callq 0xac40
movq %rax, %rdi
movq -0x20(%rbp), %rax
movq (%rax), %rsi
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rdx
callq 0xaea0
movq -0x10(%rbp), %rdi
callq 0xa200
movq %rax, -0x30(%rbp)
cmpq $0x0, %rax
jne 0x871f
movq -0x20(%rbp), %rax
movq (%rax), %rdi
callq 0x2030
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rdi
callq 0xb150
movq -0x20(%rbp), %rdi
callq 0x2030
movq $0x0, -0x8(%rbp)
jmp 0x87c2
movq -0x20(%rbp), %rax
movq (%rax), %rdi
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rsi
movq -0x30(%rbp), %rdx
callq 0x7b20
movq %rax, -0x38(%rbp)
movq -0x20(%rbp), %rdi
callq 0x2030
movq -0x38(%rbp), %rax
movq 0x8(%rax), %rax
movq 0x8(%rax), %rax
movq %rax, -0x40(%rbp)
movl $0x0, -0x44(%rbp)
movl -0x44(%rbp), %eax
movq -0x40(%rbp), %rcx
cmpl (%rcx), %eax
jge 0x87ba
movq -0x40(%rbp), %rax
movq 0x8(%rax), %rax
movslq -0x44(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x50(%rbp)
movq -0x40(%rbp), %rax
movq 0x10(%rax), %rax
movslq -0x44(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x58(%rbp)
movq -0x38(%rbp), %rax
movq 0x8(%rax), %rax
movq 0x10(%rax), %rax
movq 0x8(%rax), %rax
movq 0x10(%rax), %rdi
movq -0x50(%rbp), %rsi
movq -0x58(%rbp), %rdx
callq 0xaea0
movl -0x44(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x44(%rbp)
jmp 0x875b
movq -0x38(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x60, %rsp
popq %rbp
retq
nopl (%rax)