// File: /workspace/github_c_makefile_star2_O0/Encryptr[P]O-plus-plus/opp/analysis/analysis.c
// Function: opp_analize_struct
static void opp_analize_struct(struct Opp_Analize* ctx, struct Opp_Node* node)
{
	struct Opp_Type_Entry* t = get_type(&ctx->parser->tree, node->struct_stmt.name);
	node->struct_stmt.ns = init_namespace(NULL, (void*)alloc);
	struct Opp_Namespace* temp = ctx->curr_ns;
	ctx->curr_ns = node->struct_stmt.ns;

	unsigned int allign = 0;
	unsigned int cur_size = 0;
	struct Opp_Node** var = node->struct_stmt.elems;

	// Find largest type
	for (unsigned int i = 0; i < node->struct_stmt.len; i++) {
		opp_analize_var(ctx, node->struct_stmt.elems[i]);
		if (node->struct_stmt.elems[i]->type != STMT_VAR)
			opp_semantics_error(ctx, node, 
				"'%s' struct elements can only be var declarations", node->struct_stmt.name);

		if (node->struct_stmt.elems[i]->var_stmt.type.decl->t_type == TYPE_STRUCT &&
			node->struct_stmt.elems[i]->var_stmt.type.depth == 0 && 
			t == node->struct_stmt.elems[i]->var_stmt.type.decl)
				opp_semantics_error(ctx, node, "Cannot make struct obj of '%s' inside '%s'", t->id, t->id);
		
		unsigned int s = 0;

		if (var[i]->var_stmt.type.decl->t_type == TYPE_STRUCT 
			&& var[i]->var_stmt.type.depth == 0)
			s = var[i]->var_stmt.type.decl->l_mem;
		else 
			s = opp_get_plain_size(&var[i]->var_stmt.type);

		if (s > allign)
			allign = s;
	}

	// Calculate member offsets
	for (unsigned int i = 0; i < node->struct_stmt.len; i++) {
		unsigned int s = opp_get_plain_size(&var[i]->var_stmt.type);

		if (var[i]->var_stmt.type.decl->t_type != TYPE_I8) {
			if (cur_size != 0) {
				while (cur_size % s != 0) 
					cur_size++;
			}
		}

		if (var[i]->var_stmt.type.size > 0)
			s = var[i]->var_stmt.type.size;
		else if (var[i]->var_stmt.type.decl->t_type == TYPE_STRUCT &&
				var[i]->var_stmt.type.depth == 0)
			s = var[i]->var_stmt.type.decl->size;

		opp_add_to_struct(ctx, var[i], cur_size);

		cur_size += s;
	}

	if (node->struct_stmt.len != 0) {
		while (cur_size % allign != 0)
			cur_size++;
	}
	t->l_mem = allign;
	t->size = cur_size;
	ctx->curr_ns = temp;
}

// Assembly:
subq $0x48, %rsp
movq %rdi, 0x40(%rsp)
movq %rsi, 0x38(%rsp)
movq 0x40(%rsp), %rax
movq 0x8(%rax), %rdi
addq $0x20, %rdi
movq 0x38(%rsp), %rax
movq 0x10(%rax), %rsi
callq 0xed70
movq %rax, 0x30(%rsp)
xorl %eax, %eax
movl %eax, %edi
leaq 0xb9b7(%rip), %rsi      # 0xe190
callq 0x12990
movq %rax, %rcx
movq 0x38(%rsp), %rax
movq %rcx, 0x28(%rax)
movq 0x40(%rsp), %rax
movq 0x18(%rax), %rax
movq %rax, 0x28(%rsp)
movq 0x38(%rsp), %rax
movq 0x28(%rax), %rcx
movq 0x40(%rsp), %rax
movq %rcx, 0x18(%rax)
movl $0x0, 0x24(%rsp)
movl $0x0, 0x20(%rsp)
movq 0x38(%rsp), %rax
movq 0x20(%rax), %rax
movq %rax, 0x18(%rsp)
movl $0x0, 0x14(%rsp)
movl 0x14(%rsp), %eax
movq 0x38(%rsp), %rcx
cmpl 0x18(%rcx), %eax
jae 0x299a
movq 0x40(%rsp), %rdi
movq 0x38(%rsp), %rax
movq 0x20(%rax), %rax
movl 0x14(%rsp), %ecx
movq (%rax,%rcx,8), %rsi
callq 0x24d0
movq 0x38(%rsp), %rax
movq 0x20(%rax), %rax
movl 0x14(%rsp), %ecx
movq (%rax,%rcx,8), %rax
cmpl $0x13, (%rax)
je 0x2894
movq 0x40(%rsp), %rdi
movq 0x38(%rsp), %rsi
movq 0x38(%rsp), %rax
movq 0x10(%rax), %rcx
leaq 0x116c1(%rip), %rdx     # 0x13f4e
movb $0x0, %al
callq 0x2b10
movq 0x38(%rsp), %rax
movq 0x20(%rax), %rax
movl 0x14(%rsp), %ecx
movq (%rax,%rcx,8), %rax
movq 0x10(%rax), %rax
cmpl $0x8, 0x8(%rax)
jne 0x290d
movq 0x38(%rsp), %rax
movq 0x20(%rax), %rax
movl 0x14(%rsp), %ecx
movq (%rax,%rcx,8), %rax
movzwl 0x18(%rax), %eax
cmpl $0x0, %eax
jne 0x290d
movq 0x30(%rsp), %rax
movq 0x38(%rsp), %rcx
movq 0x20(%rcx), %rcx
movl 0x14(%rsp), %edx
movq (%rcx,%rdx,8), %rcx
cmpq 0x10(%rcx), %rax
jne 0x290d
movq 0x40(%rsp), %rdi
movq 0x38(%rsp), %rsi
movq 0x30(%rsp), %rax
movq (%rax), %rcx
movq 0x30(%rsp), %rax
movq (%rax), %r8
leaq 0x1167a(%rip), %rdx     # 0x13f80
movb $0x0, %al
callq 0x2b10
movl $0x0, 0x10(%rsp)
movq 0x18(%rsp), %rax
movl 0x14(%rsp), %ecx
movq (%rax,%rcx,8), %rax
movq 0x10(%rax), %rax
cmpl $0x8, 0x8(%rax)
jne 0x295c
movq 0x18(%rsp), %rax
movl 0x14(%rsp), %ecx
movq (%rax,%rcx,8), %rax
movzwl 0x18(%rax), %eax
cmpl $0x0, %eax
jne 0x295c
movq 0x18(%rsp), %rax
movl 0x14(%rsp), %ecx
movq (%rax,%rcx,8), %rax
movq 0x10(%rax), %rax
movl 0x14(%rax), %eax
movl %eax, 0x10(%rsp)
jmp 0x2976
movq 0x18(%rsp), %rax
movl 0x14(%rsp), %ecx
movq (%rax,%rcx,8), %rdi
addq $0x10, %rdi
callq 0x53a0
movl %eax, 0x10(%rsp)
movl 0x10(%rsp), %eax
cmpl 0x24(%rsp), %eax
jbe 0x2988
movl 0x10(%rsp), %eax
movl %eax, 0x24(%rsp)
jmp 0x298a
movl 0x14(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x14(%rsp)
jmp 0x2830
movl $0x0, 0xc(%rsp)
movl 0xc(%rsp), %eax
movq 0x38(%rsp), %rcx
cmpl 0x18(%rcx), %eax
jae 0x2ab9
movq 0x18(%rsp), %rax
movl 0xc(%rsp), %ecx
movq (%rax,%rcx,8), %rdi
addq $0x10, %rdi
callq 0x53a0
movl %eax, 0x8(%rsp)
movq 0x18(%rsp), %rax
movl 0xc(%rsp), %ecx
movq (%rax,%rcx,8), %rax
movq 0x10(%rax), %rax
cmpl $0x1, 0x8(%rax)
je 0x2a0e
cmpl $0x0, 0x20(%rsp)
je 0x2a0c
jmp 0x29ee
movl 0x20(%rsp), %eax
xorl %edx, %edx
divl 0x8(%rsp)
cmpl $0x0, %edx
je 0x2a0a
movl 0x20(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x20(%rsp)
jmp 0x29ee
jmp 0x2a0c
jmp 0x2a0e
movq 0x18(%rsp), %rax
movl 0xc(%rsp), %ecx
movq (%rax,%rcx,8), %rax
movzwl 0x1a(%rax), %eax
cmpl $0x0, %eax
jle 0x2a3b
movq 0x18(%rsp), %rax
movl 0xc(%rsp), %ecx
movq (%rax,%rcx,8), %rax
movzwl 0x1a(%rax), %eax
movl %eax, 0x8(%rsp)
jmp 0x2a82
movq 0x18(%rsp), %rax
movl 0xc(%rsp), %ecx
movq (%rax,%rcx,8), %rax
movq 0x10(%rax), %rax
cmpl $0x8, 0x8(%rax)
jne 0x2a80
movq 0x18(%rsp), %rax
movl 0xc(%rsp), %ecx
movq (%rax,%rcx,8), %rax
movzwl 0x18(%rax), %eax
cmpl $0x0, %eax
jne 0x2a80
movq 0x18(%rsp), %rax
movl 0xc(%rsp), %ecx
movq (%rax,%rcx,8), %rax
movq 0x10(%rax), %rax
movl 0x10(%rax), %eax
movl %eax, 0x8(%rsp)
jmp 0x2a82
movq 0x40(%rsp), %rdi
movq 0x18(%rsp), %rax
movl 0xc(%rsp), %ecx
movq (%rax,%rcx,8), %rsi
movl 0x20(%rsp), %edx
callq 0x5460
movl 0x8(%rsp), %eax
addl 0x20(%rsp), %eax
movl %eax, 0x20(%rsp)
movl 0xc(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xc(%rsp)
jmp 0x29a2
movq 0x38(%rsp), %rax
cmpl $0x0, 0x18(%rax)
je 0x2ae4
jmp 0x2ac6
movl 0x20(%rsp), %eax
xorl %edx, %edx
divl 0x24(%rsp)
cmpl $0x0, %edx
je 0x2ae2
movl 0x20(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x20(%rsp)
jmp 0x2ac6
jmp 0x2ae4
movl 0x24(%rsp), %ecx
movq 0x30(%rsp), %rax
movl %ecx, 0x14(%rax)
movl 0x20(%rsp), %ecx
movq 0x30(%rsp), %rax
movl %ecx, 0x10(%rax)
movq 0x28(%rsp), %rcx
movq 0x40(%rsp), %rax
movq %rcx, 0x18(%rax)
addq $0x48, %rsp
retq
nop