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

	switch (node_type->type) {
		case FE_NODE_TYPE_CHAR: {
			rstr_append_with_cstr(rstr, "char");
			break;
		}
		case FE_NODE_TYPE_INT8: {
			rstr_append_with_cstr(rstr, "int8");
			break;
		}
		case FE_NODE_TYPE_UINT8: {
			rstr_append_with_cstr(rstr, "uint8");
			break;
		}
		case FE_NODE_TYPE_INT16: {
			rstr_append_with_cstr(rstr, "int16");
			break;
		}
		case FE_NODE_TYPE_UINT16: {
			rstr_append_with_cstr(rstr, "uint16");
			break;
		}
		case FE_NODE_TYPE_INT32: {
			rstr_append_with_cstr(rstr, "int32");
			break;
		}
		case FE_NODE_TYPE_UINT32: {
			rstr_append_with_cstr(rstr, "uint32");
			break;
		}
		case FE_NODE_TYPE_INT64: {
			rstr_append_with_cstr(rstr, "int64");
			break;
		}
		case FE_NODE_TYPE_UINT64: {
			rstr_append_with_cstr(rstr, "uint64");
			break;
		}
		case FE_NODE_TYPE_FLOAT: {
			rstr_append_with_cstr(rstr, "float");
			break;
		}
		case FE_NODE_TYPE_DOUBLE: {
			rstr_append_with_cstr(rstr, "double");
			break;
		}
		case FE_NODE_TYPE_VA_LIST: {
			rstr_append_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_append_with_cstr(rstr, "struct ");

			ResizableString rstr_id;
			rstr_init(&rstr_id);
			_ir_identifier_name(ctx, &rstr_id, node_id);
			rstr_append_with_rstr(rstr, &rstr_id);
			rstr_free(&rstr_id);
			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);
			assert(node_array_dims->nchilds > 0);

			ParserASTNode *node_t = node_type->childs[1];

			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, "]");
			}

			_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];
			assert(node_params->type == FE_NODE_FUNC_PARAMS);

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

			rstr_append_with_cstr(rstr, "function");

			rstr_append_with_cstr(rstr, "(");
			_ir_func_type_params(ctx, rstr, node_params);
			rstr_append_with_cstr(rstr, ")");

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

			rstr_append_with_char(rstr, '*');

			_ir_type(ctx, rstr, node_t);
			break;
		}
		case FE_NODE_TYPE_VOID: {
			// 什么都不做。
			break;
		}
		default: {
			assert(0);
			break;
		}
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rsi, %r13
movq %rdi, %rbx
leaq 0x355b9(%rip), %r14     # 0x421cc
leaq 0x35bf3(%rip), %r15     # 0x4280d
testq %rbx, %rbx
je 0xcf07
testq %r13, %r13
je 0xcf26
movl (%r13), %eax
cmpl $0x42f, %eax            # imm = 0x42F
jle 0xcc6e
cmpl $0x430, %eax            # imm = 0x430
je 0xccc6
cmpl $0x440, %eax            # imm = 0x440
jne 0xcda4
cmpl $0x1, 0x44(%r13)
jne 0xcf45
movq 0x48(%r13), %rax
movq (%rax), %r13
movq %rbx, %rdi
movl $0x2a, %esi
callq 0x76cb
jmp 0xcc1a
addl $0xfffffc00, %eax       # imm = 0xFFFFFC00
cmpl $0x20, %eax
ja 0xcdaf
movslq (%r14,%rax,4), %rax
addq %r14, %rax
jmpq *%rax
cmpl $0x2, 0x44(%r13)
jne 0xcfa2
movq 0x48(%r13), %rax
movq (%rax), %r12
cmpl $0x421, (%r12)          # imm = 0x421
jne 0xcfc1
cmpl $0x0, 0x44(%r12)
jle 0xcfe0
movq 0x8(%rax), %r13
cmpl $0x0, 0x44(%r12)
jg 0xcd48
jmp 0xcc1a
movl 0x44(%r13), %eax
leal -0x1(%rax), %ecx
cmpl $0x2, %ecx
jae 0xcf64
movq 0x48(%r13), %rcx
movq (%rcx), %r12
cmpl $0xa01, (%r12)          # imm = 0xA01
jne 0xcf83
cmpl $0x2, %eax
jne 0xccf6
movq 0x8(%rcx), %r13
jmp 0xccf9
xorl %r13d, %r13d
movq %rbx, %rdi
movq %r15, %rsi
callq 0x75cf
movq %rbx, %rdi
leaq 0x3866b(%rip), %rsi     # 0x45379
callq 0x75cf
movq %rbx, %rdi
movq %r12, %rsi
callq 0xd7dd
movq %rbx, %rdi
leaq 0x37c12(%rip), %rsi     # 0x4493a
callq 0x75cf
testq %r13, %r13
je 0xceb3
movq %rbx, %rdi
movl $0x3a, %esi
callq 0x76cb
jmp 0xcc1a
xorl %r14d, %r14d
movq 0x48(%r12), %rax
movq (%rax,%r14,8), %r15
cmpl $0x300, (%r15)          # imm = 0x300
jne 0xcee8
movq %rbx, %rdi
leaq 0x35a44(%rip), %rsi     # 0x427af
callq 0x75cf
movq 0x10(%r15), %rax
movq 0x8(%rax), %rsi
movl 0x4(%rax), %edx
movq %rbx, %rdi
callq 0x7768
movq %rbx, %rdi
leaq 0x3f990(%rip), %rsi     # 0x4c71d
callq 0x75cf
incq %r14
movslq 0x44(%r12), %rax
cmpq %rax, %r14
jl 0xcd4b
jmp 0xcc0c
cmpl $0x4ff, %eax            # imm = 0x4FF
je 0xceb3
leaq 0x335ce(%rip), %rdi     # 0x40384
leaq 0x3555b(%rip), %rsi     # 0x42318
leaq 0x358ab(%rip), %rcx     # 0x4266f
movl $0x15c, %edx            # imm = 0x15C
callq 0x30a0
leaq 0x35905(%rip), %rsi     # 0x426da
jmp 0xced2
leaq 0x358f3(%rip), %rsi     # 0x426d4
jmp 0xced2
leaq 0x358da(%rip), %rsi     # 0x426c7
jmp 0xced2
leaq 0x358d4(%rip), %rsi     # 0x426cd
jmp 0xced2
leaq 0x358bc(%rip), %rsi     # 0x426c1
jmp 0xced2
leaq 0x358d0(%rip), %rsi     # 0x426e1
jmp 0xced2
leaq 0x358be(%rip), %rsi     # 0x426db
jmp 0xced2
leaq 0x3589d(%rip), %rsi     # 0x426c6
jmp 0xced2
leaq 0x35897(%rip), %rsi     # 0x426cc
jmp 0xced2
leaq 0x35892(%rip), %rsi     # 0x426d3
jmp 0xced2
cmpl $0x1, 0x44(%r13)
jne 0xcfff
movq 0x48(%r13), %rax
movq (%rax), %r15
cmpl $0x200, (%r15)          # imm = 0x200
jne 0xd01e
leaq 0x3703e(%rip), %rsi     # 0x43eaa
movq %rbx, %rdi
callq 0x75cf
leaq -0x38(%rbp), %r14
movq %r14, %rdi
callq 0x7548
movq %r14, %rdi
movl $0x5f, %esi
callq 0x76cb
movq 0x10(%r15), %rax
movq 0x8(%rax), %rsi
movl 0x4(%rax), %edx
movq %r14, %rdi
callq 0x7768
movq %rbx, %rdi
movq %r14, %rsi
callq 0x788c
movq %r14, %rdi
callq 0x7a38
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x3581e(%rip), %rsi     # 0x426e7
jmp 0xced2
leaq 0x3581c(%rip), %rsi     # 0x426ee
movq %rbx, %rdi
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x75cf
leaq 0x35893(%rip), %rdi     # 0x42782
leaq 0x35422(%rip), %rsi     # 0x42318
leaq 0x35772(%rip), %rcx     # 0x4266f
movl $0x12a, %edx            # imm = 0x12A
callq 0x30a0
leaq 0x33b42(%rip), %rdi     # 0x40a50
leaq 0x35403(%rip), %rsi     # 0x42318
leaq 0x35753(%rip), %rcx     # 0x4266f
movl $0xdc, %edx
callq 0x30a0
leaq 0x3578a(%rip), %rdi     # 0x426b7
leaq 0x353e4(%rip), %rsi     # 0x42318
leaq 0x35734(%rip), %rcx     # 0x4266f
movl $0xdd, %edx
callq 0x30a0
leaq 0x357ac(%rip), %rdi     # 0x426f8
leaq 0x353c5(%rip), %rsi     # 0x42318
leaq 0x35715(%rip), %rcx     # 0x4266f
movl $0x14f, %edx            # imm = 0x14F
callq 0x30a0
leaq 0x35846(%rip), %rdi     # 0x427b1
leaq 0x353a6(%rip), %rsi     # 0x42318
leaq 0x356f6(%rip), %rcx     # 0x4266f
movl $0x136, %edx            # imm = 0x136
callq 0x30a0
leaq 0x3585a(%rip), %rdi     # 0x427e4
leaq 0x35387(%rip), %rsi     # 0x42318
leaq 0x356d7(%rip), %rcx     # 0x4266f
movl $0x13b, %edx            # imm = 0x13B
callq 0x30a0
leaq 0x35823(%rip), %rdi     # 0x427cc
leaq 0x35368(%rip), %rsi     # 0x42318
leaq 0x356b8(%rip), %rcx     # 0x4266f
movl $0x120, %edx            # imm = 0x120
callq 0x30a0
leaq 0x3576c(%rip), %rdi     # 0x42734
leaq 0x35349(%rip), %rsi     # 0x42318
leaq 0x35699(%rip), %rcx     # 0x4266f
movl $0x123, %edx            # imm = 0x123
callq 0x30a0
leaq 0x3577e(%rip), %rdi     # 0x42765
leaq 0x3532a(%rip), %rsi     # 0x42318
leaq 0x3567a(%rip), %rcx     # 0x4266f
movl $0x124, %edx            # imm = 0x124
callq 0x30a0
leaq 0x356f2(%rip), %rdi     # 0x426f8
leaq 0x3530b(%rip), %rsi     # 0x42318
leaq 0x3565b(%rip), %rcx     # 0x4266f
movl $0x111, %edx            # imm = 0x111
callq 0x30a0
leaq 0x356eb(%rip), %rdi     # 0x42710
leaq 0x352ec(%rip), %rsi     # 0x42318
leaq 0x3563c(%rip), %rcx     # 0x4266f
movl $0x114, %edx            # imm = 0x114
callq 0x30a0