// File: /workspace/github_c_makefile_star2_O3/Encryptr[P]O-plus-plus/opp/analysis/analysis.c
// Function: opp_analize_var
static void opp_analize_var(struct Opp_Analize* ctx, struct Opp_Node* node)
{
	struct Opp_Stmt_Var* var = &node->var_stmt;
	struct Opp_Node* name = NULL;
	bool assign = false;

	unsigned int size = get_type_size(&var->type);
	if (size == 0)
		opp_semantics_error(ctx, node, "Cannot use type 'void' to declare a variable");

	switch (var->var->type)
	{
		case EUNARY: {
			name = var->var;
			break;
		}

		case EELEMENT: {
			name = var->var->elem_expr.name;

			while (name->type != EUNARY) {
				if (name->type != EELEMENT)
					opp_semantics_error(ctx, node, 
						"Unexpected token in array declaration");

				if (name->elem_expr.loc->unary_expr.type != TINTEGER)
					opp_semantics_error(ctx, node,
						"Non constant values not allowed in array declaration");
				size *= name->elem_expr.loc->unary_expr.val.i64val;				
				name = name->elem_expr.name;
			}

			if (var->var->elem_expr.loc->unary_expr.type != TINTEGER)
				opp_semantics_error(ctx, node,
					"Non constant values not allowed in array declaration '%s'", name->unary_expr.val.strval);

			size *= var->var->elem_expr.loc->unary_expr.val.i64val;
			var->type.depth = 1;
			var->type.size = size;
			var->var = name;
			break;
		}

		case EASSIGN: {
			name = var->var->assign_expr.ident;

			if (var->var->assign_expr.ident->type == EELEMENT)
				opp_semantics_error(ctx, node, "Assigning array type variables not allowed");

			assign = true;
			break;
		}

		default: break;
	}

	struct Opp_Bucket* bucket = env_add_item(ctx->curr_ns, name->unary_expr.val.strval);

	if (bucket == NULL)
		opp_semantics_error(ctx, node, "Redeclaration of variable '%s'",
			name->unary_expr.val.strval);

	ctx->debug.res_name = name->unary_expr.val.strval;

	bucket->key = name->unary_expr.val.strval;
	bucket->type = ctx->curr_ns == ctx->ns ? TYPE_GLOBAL : TYPE_LOCAL;
	bucket->sym_type = var->type;
	var->bidx = bucket;

	if (assign)
		opp_analize_assign(ctx, var->var);
}

// Assembly:
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
movq %rsi, %rbx
movq %rdi, %r14
leaq 0x10(%rsi), %r15
movq %r15, %rdi
callq 0x36bd
testl %eax, %eax
je 0x225c
movq 0x20(%rbx), %r12
movl (%r12), %ecx
cmpl $0x4, %ecx
je 0x218d
cmpl $0x5, %ecx
je 0x2188
cmpl $0x7, %ecx
jne 0x21a8
movq %r12, %rcx
movq 0x10(%rcx), %rcx
movl (%rcx), %edx
cmpl $0x7, %edx
jne 0x21b0
movq 0x18(%rcx), %rdx
cmpl $0x2, 0x10(%rdx)
jne 0x2248
imull 0x18(%rdx), %eax
jmp 0x2169
xorl %r13d, %r13d
jmp 0x21e0
movq 0x20(%r12), %r12
movb $0x1, %r13b
cmpl $0x7, (%r12)
jne 0x21e0
leaq 0x9cd4(%rip), %rdx      # 0xbe77
jmp 0x224f
xorl %r13d, %r13d
xorl %r12d, %r12d
jmp 0x21e0
cmpl $0x5, %edx
jne 0x223f
movq 0x18(%r12), %rdx
cmpl $0x2, 0x10(%rdx)
jne 0x2279
imull 0x18(%rdx), %eax
movw $0x1, 0x18(%rbx)
movw %ax, 0x1a(%rbx)
movq %rcx, 0x20(%rbx)
xorl %r13d, %r13d
movq %rcx, %r12
movq 0x18(%r14), %rdi
movq 0x18(%r12), %rsi
callq 0xa281
movq 0x18(%r12), %rcx
testq %rax, %rax
je 0x2265
movq %rcx, 0x40(%r14)
movq %rcx, (%rax)
movq 0x18(%r14), %rcx
xorl %edx, %edx
cmpq 0x10(%r14), %rcx
setne %dl
movl %edx, 0x8(%rax)
movups (%r15), %xmm0
movups %xmm0, 0x10(%rax)
movq %rax, 0x28(%rbx)
testb %r13b, %r13b
je 0x2235
movq 0x20(%rbx), %rsi
movq %r14, %rdi
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
jmp 0x26cd
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
retq
leaq 0x9b9c(%rip), %rdx      # 0xbde2
jmp 0x224f
leaq 0x9bb9(%rip), %rdx      # 0xbe08
movq %r14, %rdi
movq %rbx, %rsi
xorl %eax, %eax
callq 0x2286
leaq 0x9b52(%rip), %rdx      # 0xbdb5
jmp 0x224f
leaq 0x9c36(%rip), %rdx      # 0xbea2
movq %r14, %rdi
movq %rbx, %rsi
xorl %eax, %eax
callq 0x2286
movq 0x18(%rcx), %rcx
leaq 0x9bb9(%rip), %rdx      # 0xbe3d
jmp 0x226c