// File: /workspace/github_c_makefile_star2_O3/Ihsoh[P]ilang/compiler/frontend/irgen_c.c
// Function: ir_type
static void _ir_type(
	IRGeneratorCContext *ctx,
	ResizableString *rstr,
	ParserASTNode *node_type
) {
	assert(ctx);
	assert(rstr);
	assert(node_type);

	switch (node_type->type) {
		case FE_NODE_TYPE_CHAR: {
			rstr_prepend_with_cstr(rstr, "char ");
			break;
		}
		case FE_NODE_TYPE_INT8: {
			rstr_prepend_with_cstr(rstr, "int8_t ");
			break;
		}
		case FE_NODE_TYPE_UINT8: {
			rstr_prepend_with_cstr(rstr, "uint8_t ");
			break;
		}
		case FE_NODE_TYPE_INT16: {
			rstr_prepend_with_cstr(rstr, "int16_t ");
			break;
		}
		case FE_NODE_TYPE_UINT16: {
			rstr_prepend_with_cstr(rstr, "uint16_t ");
			break;
		}
		case FE_NODE_TYPE_INT32: {
			rstr_prepend_with_cstr(rstr, "int32_t ");
			break;
		}
		case FE_NODE_TYPE_UINT32: {
			rstr_prepend_with_cstr(rstr, "uint32_t ");
			break;
		}
		case FE_NODE_TYPE_INT64: {
			rstr_prepend_with_cstr(rstr, "int64_t ");
			break;
		}
		case FE_NODE_TYPE_UINT64: {
			rstr_prepend_with_cstr(rstr, "uint64_t ");
			break;
		}
		case FE_NODE_TYPE_FLOAT: {
			rstr_prepend_with_cstr(rstr, "float ");
			break;
		}
		case FE_NODE_TYPE_DOUBLE: {
			rstr_prepend_with_cstr(rstr, "double ");
			break;
		}
		case FE_NODE_TYPE_VA_LIST: {
			rstr_prepend_with_cstr(rstr, "va_list ");
			break;
		}
		case FE_NODE_TYPE_STRUCT: {
			assert(node_type->nchilds == 1);

			ParserASTNode *node_id = node_type->childs[0];
			assert(node_id->type == FE_NODE_IDENTIFIER);

			rstr_prepend_with_cstr(rstr, " ");
			rstr_prepend_with_raw(rstr, node_id->token->content, node_id->token->len);
			rstr_prepend_with_cstr(rstr, "struct ");
			break;
		}
		case FE_NODE_TYPE_ARRAY: {
			assert(node_type->nchilds == 2);
			ParserASTNode *node_array_dims = node_type->childs[0];
			assert(node_array_dims->type == FE_NODE_TYPE_ARRAY_DIMS);
			ParserASTNode *node_t = node_type->childs[1];

			rstr_prepend_with_cstr(rstr, "(");
			for (int i = 0; i < node_array_dims->nchilds; i++) {
				ParserASTNode *node_array_dim = node_array_dims->childs[i];
				assert(node_array_dim->type == FE_NODE_LITERAL_UINT);
				rstr_append_with_cstr(rstr, "[");
				rstr_append_with_raw(rstr, node_array_dim->token->content, node_array_dim->token->len);
				rstr_append_with_cstr(rstr, "]");
			}
			rstr_append_with_cstr(rstr, ")");

			_ir_type(ctx, rstr, node_t);
			break;
		}
		case FE_NODE_TYPE_FUNC: {
			assert(node_type->nchilds == 1 || node_type->nchilds == 2);
			ParserASTNode *node_params = NULL;
			ParserASTNode *node_t = NULL;

			node_params = node_type->childs[0];
			if (node_type->nchilds == 2) {
				node_t = node_type->childs[1];
			}

			rstr_prepend_with_cstr(rstr, "(");
			rstr_append_with_cstr(rstr, ")(");
			_ir_func_params(ctx, rstr, node_params);
			rstr_append_with_cstr(rstr, ")");

			if (node_t != NULL) {
				_ir_type(ctx, rstr, node_t);
			} else {
				rstr_prepend_with_cstr(rstr, "void(");
				rstr_append_with_cstr(rstr, ")");
			}
			break;
		}
		case FE_NODE_TYPE_POINTER: {
			assert(node_type->nchilds == 1);
			ParserASTNode *node_t = node_type->childs[0];
			
			rstr_prepend_with_cstr(rstr, "(*");
			rstr_append_with_cstr(rstr, ")");

			_ir_type(ctx, rstr, node_t);
			break;
		}
		case FE_NODE_TYPE_VOID: {
			rstr_prepend_with_cstr(rstr, "void ");
			break;
		}
		default: {
			assert(0);
			break;
		}
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
testq %rdi, %rdi
je 0x14c9c
movq %rsi, %r14
testq %rsi, %rsi
je 0x14aa7
movq %rdi, %rbx
leaq 0x2ed8e(%rip), %r12     # 0x436bc
leaq 0x2fb11(%rip), %r13     # 0x44446
movl (%r14), %eax
cmpl $0x42f, %eax            # imm = 0x42F
jle 0x1497b
cmpl $0x430, %eax            # imm = 0x430
je 0x14a3c
cmpl $0x440, %eax            # imm = 0x440
jne 0x14ac6
cmpl $0x1, 0x44(%r14)
jne 0x14c3f
movq 0x48(%r14), %rax
movq (%rax), %r14
movq %rbx, %rdi
leaq 0x2f132(%rip), %rsi     # 0x43aa3
callq 0x7db4
jmp 0x14a2b
addl $0xfffffc00, %eax       # imm = 0xFFFFFC00
cmpl $0x20, %eax
ja 0x14c7d
movslq (%r12,%rax,4), %rax
addq %r12, %rax
jmpq *%rax
cmpl $0x2, 0x44(%r14)
jne 0x14c01
movq 0x48(%r14), %rax
movq (%rax), %r15
cmpl $0x421, (%r15)          # imm = 0x421
jne 0x14c20
movq 0x8(%rax), %r14
movq %rbx, %rdi
movq %r13, %rsi
callq 0x7db4
cmpl $0x0, 0x44(%r15)
jle 0x14a2b
xorl %r12d, %r12d
movq 0x48(%r15), %rax
movq (%rax,%r12,8), %r13
cmpl $0x300, (%r13)          # imm = 0x300
jne 0x14be2
movq %rbx, %rdi
leaq 0x2ce11(%rip), %rsi     # 0x417fb
callq 0x73db
movq 0x10(%r13), %rax
movq 0x8(%rax), %rsi
movl 0x4(%rax), %edx
movq %rbx, %rdi
callq 0x7577
movq %rbx, %rdi
leaq 0x36db1(%rip), %rsi     # 0x4b7bd
callq 0x73db
incq %r12
movslq 0x44(%r15), %rax
cmpq %rax, %r12
jl 0x149ca
leaq 0x2ec98(%rip), %r12     # 0x436bc
leaq 0x2fa1b(%rip), %r13     # 0x44446
movq %rbx, %rdi
leaq 0x2efd5(%rip), %rsi     # 0x43a0a
callq 0x73db
jmp 0x14a9e
movl 0x44(%r14), %ecx
leal -0x1(%rcx), %eax
cmpl $0x2, %eax
jae 0x14c5e
movq 0x48(%r14), %rax
cmpl $0x2, %ecx
jne 0x14a5b
movq 0x8(%rax), %r14
jmp 0x14a5e
xorl %r14d, %r14d
movq (%rax), %r15
movq %rbx, %rdi
movq %r13, %rsi
callq 0x7db4
movq %rbx, %rdi
leaq 0x2f024(%rip), %rsi     # 0x43a9a
callq 0x73db
movq %rbx, %rdi
movq %r15, %rsi
callq 0x14de0
movq %rbx, %rdi
leaq 0x2ef7a(%rip), %rsi     # 0x43a0a
callq 0x73db
testq %r14, %r14
je 0x14bb6
testq %r14, %r14
jne 0x14935
leaq 0x2cc55(%rip), %rdi     # 0x41703
leaq 0x2edd7(%rip), %rsi     # 0x4388c
leaq 0x2ef50(%rip), %rcx     # 0x43a0c
movl $0x29, %edx
callq 0x30a0
cmpl $0x4ff, %eax            # imm = 0x4FF
jne 0x14c7d
leaq 0x2efce(%rip), %rsi     # 0x43aa6
jmp 0x14ba0
leaq 0x2ef8a(%rip), %rsi     # 0x43a6e
jmp 0x14ba0
leaq 0x2ef99(%rip), %rsi     # 0x43a89
jmp 0x14ba0
leaq 0x2ef5f(%rip), %rsi     # 0x43a5b
jmp 0x14ba0
leaq 0x2ef67(%rip), %rsi     # 0x43a6f
jmp 0x14ba0
leaq 0x2ef48(%rip), %rsi     # 0x43a5c
jmp 0x14ba0
leaq 0x2ef59(%rip), %rsi     # 0x43a79
jmp 0x14ba0
leaq 0x2ef2c(%rip), %rsi     # 0x43a55
jmp 0x14ba0
leaq 0x2ef33(%rip), %rsi     # 0x43a65
jmp 0x14ba0
leaq 0x2ef3d(%rip), %rsi     # 0x43a78
jmp 0x14ba0
leaq 0x2ef20(%rip), %rsi     # 0x43a64
jmp 0x14ba0
leaq 0x2ef35(%rip), %rsi     # 0x43a82
jmp 0x14ba0
cmpl $0x1, 0x44(%r14)
jne 0x14cbb
movq 0x48(%r14), %rax
movq (%rax), %r14
cmpl $0x200, (%r14)          # imm = 0x200
jne 0x14cda
leaq 0x2b7d9(%rip), %rsi     # 0x4034e
movq %rbx, %rdi
callq 0x7db4
movq 0x10(%r14), %rax
movq 0x8(%rax), %rsi
movl 0x4(%rax), %edx
movq %rbx, %rdi
callq 0x7de4
leaq 0x2e35f(%rip), %rsi     # 0x42ef6
jmp 0x14ba0
leaq 0x2eef1(%rip), %rsi     # 0x43a91
movq %rbx, %rdi
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x7db4
leaq 0x2eee0(%rip), %rsi     # 0x43a9d
movq %rbx, %rdi
callq 0x7db4
leaq 0x2ee3e(%rip), %rsi     # 0x43a0a
movq %rbx, %rdi
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x73db
leaq 0x2cbe5(%rip), %rdi     # 0x417ce
leaq 0x2ec9c(%rip), %rsi     # 0x4388c
leaq 0x2ee15(%rip), %rcx     # 0x43a0c
movl $0x70, %edx
callq 0x30a0
leaq 0x2cc10(%rip), %rdi     # 0x41818
leaq 0x2ec7d(%rip), %rsi     # 0x4388c
leaq 0x2edf6(%rip), %rcx     # 0x43a0c
movl $0x68, %edx
callq 0x30a0
leaq 0x2cb59(%rip), %rdi     # 0x41780
leaq 0x2ec5e(%rip), %rsi     # 0x4388c
leaq 0x2edd7(%rip), %rcx     # 0x43a0c
movl $0x6a, %edx
callq 0x30a0
leaq 0x2cafe(%rip), %rdi     # 0x41744
leaq 0x2ec3f(%rip), %rsi     # 0x4388c
leaq 0x2edb8(%rip), %rcx     # 0x43a0c
movl $0x92, %edx
callq 0x30a0
leaq 0x2cb98(%rip), %rdi     # 0x417fd
leaq 0x2ec20(%rip), %rsi     # 0x4388c
leaq 0x2ed99(%rip), %rcx     # 0x43a0c
movl $0x7b, %edx
callq 0x30a0
leaq 0x2a6dc(%rip), %rdi     # 0x3f360
leaq 0x2ec01(%rip), %rsi     # 0x4388c
leaq 0x2ed7a(%rip), %rcx     # 0x43a0c
movl $0xa0, %edx
callq 0x30a0
leaq 0x2ad8d(%rip), %rdi     # 0x3fa30
leaq 0x2ebe2(%rip), %rsi     # 0x4388c
leaq 0x2ed5b(%rip), %rcx     # 0x43a0c
movl $0x28, %edx
callq 0x30a0
leaq 0x2ca82(%rip), %rdi     # 0x41744
leaq 0x2ebc3(%rip), %rsi     # 0x4388c
leaq 0x2ed3c(%rip), %rcx     # 0x43a0c
movl $0x5d, %edx
callq 0x30a0
leaq 0x2ca7b(%rip), %rdi     # 0x4175c
leaq 0x2eba4(%rip), %rsi     # 0x4388c
leaq 0x2ed1d(%rip), %rcx     # 0x43a0c
movl $0x60, %edx
callq 0x30a0