// File: /workspace/github_c_makefile_star2_O2/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 0x13f12
movq %rsi, %r15
movq %rdi, %rbx
leaq 0x2d8ac(%rip), %r14     # 0x41471
leaq 0x2ce66(%rip), %r12     # 0x40a32
testq %r15, %r15
je 0x13e6a
movl (%r15), %eax
leal -0x400(%rax), %ecx
cmpl $0x20, %ecx
jbe 0x13c1f
cmpl $0x430, %eax            # imm = 0x430
je 0x13cb5
cmpl $0x440, %eax            # imm = 0x440
jne 0x13d5d
cmpl $0x1, 0x44(%r15)
jne 0x13ebb
movq 0x48(%r15), %rax
movq (%rax), %r15
movq %rbx, %rdi
leaq 0x2ceb9(%rip), %rsi     # 0x40ace
callq 0x7808
jmp 0x13ce2
leaq 0x2caa6(%rip), %rdx     # 0x406cc
movslq (%rdx,%rcx,4), %rax
addq %rdx, %rax
jmpq *%rax
cmpl $0x2, 0x44(%r15)
jne 0x13eda
movq 0x48(%r15), %rax
movq (%rax), %r13
cmpl $0x421, (%r13)          # imm = 0x421
jne 0x13ef6
movq 0x8(%rax), %r15
movq %rbx, %rdi
movq %r14, %rsi
callq 0x7808
xorl %r12d, %r12d
movslq 0x44(%r13), %rax
cmpq %rax, %r12
jge 0x13cd4
movq 0x48(%r13), %rax
movq (%rax,%r12,8), %r14
cmpl $0x300, (%r14)          # imm = 0x300
jne 0x13e4d
movq %rbx, %rdi
leaq 0x2ab82(%rip), %rsi     # 0x3e80b
callq 0x6e99
movq 0x10(%r14), %rax
movq 0x8(%rax), %rsi
movl 0x4(%rax), %edx
movq %rbx, %rdi
callq 0x700f
movq %rbx, %rdi
leaq 0x34b52(%rip), %rsi     # 0x487fd
callq 0x6e99
incq %r12
jmp 0x13c61
movl 0x44(%r15), %ecx
leal -0x1(%rcx), %eax
cmpl $0x2, %eax
jae 0x13ea2
movq 0x48(%r15), %rax
cmpl $0x2, %ecx
jne 0x13cf2
movq 0x8(%rax), %r15
jmp 0x13cf5
leaq 0x2d796(%rip), %r14     # 0x41471
leaq 0x2cd50(%rip), %r12     # 0x40a32
movq %rbx, %rdi
movq %r12, %rsi
callq 0x6e99
jmp 0x13bcc
xorl %r15d, %r15d
movq (%rax), %r13
movq %rbx, %rdi
movq %r14, %rsi
callq 0x7808
movq %rbx, %rdi
leaq 0x2cdb8(%rip), %rsi     # 0x40ac5
callq 0x6e99
movq %rbx, %rdi
movq %r13, %rsi
callq 0x1404d
movq %rbx, %rdi
movq %r12, %rsi
callq 0x6e99
testq %r15, %r15
jne 0x13bcc
leaq 0x2cd90(%rip), %rsi     # 0x40ac8
movq %rbx, %rdi
callq 0x7808
leaq 0x2cceb(%rip), %rsi     # 0x40a32
movq %rbx, %rdi
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x6e99
cmpl $0x4ff, %eax            # imm = 0x4FF
jne 0x13e83
leaq 0x2cd62(%rip), %rsi     # 0x40ad1
jmp 0x13e37
leaq 0x2cd1e(%rip), %rsi     # 0x40a99
jmp 0x13e37
leaq 0x2cd1c(%rip), %rsi     # 0x40aa3
jmp 0x13e37
leaq 0x2cd21(%rip), %rsi     # 0x40ab4
jmp 0x13e37
leaq 0x2ccf0(%rip), %rsi     # 0x40a8f
jmp 0x13e37
leaq 0x2ccef(%rip), %rsi     # 0x40a9a
jmp 0x13e37
cmpl $0x1, 0x44(%r15)
jne 0x13f2e
movq 0x48(%r15), %rax
movq (%rax), %r14
cmpl $0x200, (%r14)          # imm = 0x200
jne 0x13f4a
leaq 0x2958c(%rip), %rsi     # 0x3d362
movq %rbx, %rdi
callq 0x7808
movq 0x10(%r14), %rax
movq 0x8(%rax), %rsi
movl 0x4(%rax), %edx
movq %rbx, %rdi
callq 0x7835
leaq 0x2c10e(%rip), %rsi     # 0x3ff06
jmp 0x13e37
leaq 0x2cc85(%rip), %rsi     # 0x40a86
jmp 0x13e37
leaq 0x2cc7d(%rip), %rsi     # 0x40a87
jmp 0x13e37
leaq 0x2cc6d(%rip), %rsi     # 0x40a80
jmp 0x13e37
leaq 0x2cc91(%rip), %rsi     # 0x40aad
jmp 0x13e37
leaq 0x2cc7f(%rip), %rsi     # 0x40aa4
jmp 0x13e37
leaq 0x2cc62(%rip), %rsi     # 0x40a90
jmp 0x13e37
leaq 0x2cc85(%rip), %rsi     # 0x40abc
movq %rbx, %rdi
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x7808
leaq 0x2a98a(%rip), %rdi     # 0x3e7de
leaq 0x2ca59(%rip), %rsi     # 0x408b4
leaq 0x2cbd5(%rip), %rcx     # 0x40a37
pushq $0x70
popq %rdx
callq 0x30a0
leaq 0x2a8a2(%rip), %rdi     # 0x3e713
leaq 0x2ca3c(%rip), %rsi     # 0x408b4
leaq 0x2cbb8(%rip), %rcx     # 0x40a37
pushq $0x29
jmp 0x13e64
leaq 0x284d6(%rip), %rdi     # 0x3c360
leaq 0x2ca23(%rip), %rsi     # 0x408b4
leaq 0x2cb9f(%rip), %rcx     # 0x40a37
movl $0xa0, %edx
callq 0x30a0
leaq 0x2a964(%rip), %rdi     # 0x3e80d
leaq 0x2ca04(%rip), %rsi     # 0x408b4
leaq 0x2cb80(%rip), %rcx     # 0x40a37
pushq $0x7b
jmp 0x13e64
leaq 0x2a892(%rip), %rdi     # 0x3e754
leaq 0x2c9eb(%rip), %rsi     # 0x408b4
leaq 0x2cb67(%rip), %rcx     # 0x40a37
movl $0x92, %edx
callq 0x30a0
leaq 0x2a947(%rip), %rdi     # 0x3e828
leaq 0x2c9cc(%rip), %rsi     # 0x408b4
leaq 0x2cb48(%rip), %rcx     # 0x40a37
pushq $0x68
jmp 0x13e64
leaq 0x2a893(%rip), %rdi     # 0x3e790
leaq 0x2c9b0(%rip), %rsi     # 0x408b4
leaq 0x2cb2c(%rip), %rcx     # 0x40a37
pushq $0x6a
jmp 0x13e64
leaq 0x28b17(%rip), %rdi     # 0x3ca30
leaq 0x2c994(%rip), %rsi     # 0x408b4
leaq 0x2cb10(%rip), %rcx     # 0x40a37
pushq $0x28
jmp 0x13e64
leaq 0x2a81f(%rip), %rdi     # 0x3e754
leaq 0x2c978(%rip), %rsi     # 0x408b4
leaq 0x2caf4(%rip), %rcx     # 0x40a37
pushq $0x5d
jmp 0x13e64
leaq 0x2a81b(%rip), %rdi     # 0x3e76c
leaq 0x2c95c(%rip), %rsi     # 0x408b4
leaq 0x2cad8(%rip), %rcx     # 0x40a37
pushq $0x60
jmp 0x13e64