// File: /workspace/github_c_makefile_star2_O1/lucvoo[P]sparse-dev/evaluate.c
// Function: evaluate_offsetof
static struct symbol *evaluate_offsetof(struct expression *expr)
{
	struct expression *e = expr->down;
	struct symbol *ctype = expr->in;
	int class;

	if (expr->op == '.') {
		struct symbol *field;
		int offset = 0;
		if (!ctype) {
			expression_error(expr, "expected structure or union");
			return NULL;
		}
		examine_symbol_type(ctype);
		class = classify_type(ctype, &ctype);
		if (class != TYPE_COMPOUND) {
			expression_error(expr, "expected structure or union");
			return NULL;
		}

		field = find_identifier(expr->ident, ctype->symbol_list, &offset);
		if (!field) {
			expression_error(expr, "unknown member");
			return NULL;
		}
		ctype = field;
		expr->type = EXPR_VALUE;
		expr->flags = CEF_SET_ICE;
		expr->value = offset;
		expr->taint = 0;
		expr->ctype = size_t_ctype;
	} else {
		if (!ctype) {
			expression_error(expr, "expected structure or union");
			return NULL;
		}
		examine_symbol_type(ctype);
		class = classify_type(ctype, &ctype);
		if (class != (TYPE_COMPOUND | TYPE_PTR)) {
			expression_error(expr, "expected array");
			return NULL;
		}
		ctype = ctype->ctype.base_type;
		if (!expr->index) {
			expr->type = EXPR_VALUE;
			expr->flags = CEF_SET_ICE;
			expr->value = 0;
			expr->taint = 0;
			expr->ctype = size_t_ctype;
		} else {
			struct expression *idx = expr->index, *m;
			struct symbol *i_type = evaluate_expression(idx);
			unsigned old_idx_flags;
			int i_class = classify_type(i_type, &i_type);

			if (!is_int(i_class)) {
				expression_error(expr, "non-integer index");
				return NULL;
			}
			unrestrict(idx, i_class, &i_type);
			old_idx_flags = idx->flags;
			idx = cast_to(idx, size_t_ctype);
			idx->flags = old_idx_flags;
			m = alloc_const_expression(expr->pos,
						   bits_to_bytes(ctype->bit_size));
			m->ctype = size_t_ctype;
			m->flags = CEF_SET_INT;
			expr->type = EXPR_BINOP;
			expr->left = idx;
			expr->right = m;
			expr->op = '*';
			expr->ctype = size_t_ctype;
			expr->flags = m->flags & idx->flags & ~CEF_CONST_MASK;
		}
	}
	if (e) {
		struct expression *copy = __alloc_expression(0);
		*copy = *expr;
		if (e->type == EXPR_OFFSETOF)
			e->in = ctype;
		if (!evaluate_expression(e))
			return NULL;
		expr->type = EXPR_BINOP;
		expr->flags = e->flags & copy->flags & ~CEF_CONST_MASK;
		expr->op = '+';
		expr->ctype = size_t_ctype;
		expr->left = copy;
		expr->right = e;
	}
	return size_t_ctype;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rdi, %rbx
movq 0x28(%rdi), %r14
movq 0x20(%rdi), %r15
cmpl $0x2e, 0x4(%rdi)
jne 0x368d5
movl $0x0, 0xc(%rsp)
leaq 0x14d2d(%rip), %r12     # 0x4b57f
testq %r15, %r15
je 0x369f4
movq %r15, %rdi
callq 0x2b5f4
cmpb $0x3, (%r15)
jne 0x3686d
movq 0x60(%r15), %r15
cmpb $0xa, (%r15)
jne 0x36887
movq %r15, %rdi
callq 0x2b5f4
movq %rax, %r15
cmpb $0x3, (%rax)
jne 0x36887
movq 0x60(%r15), %r15
cmpb $0x9, (%r15)
jne 0x36891
movq 0x60(%r15), %r15
movzbl (%r15), %eax
addl $-0x7, %eax
cmpl $0x1, %eax
ja 0x369f4
movq 0x30(%rbx), %rdi
movq 0x98(%r15), %rsi
leaq 0xc(%rsp), %rdx
callq 0x38549
testq %rax, %rax
je 0x369ed
movq %rax, %r15
movw $0x3001, (%rbx)         # imm = 0x3001
movslq 0xc(%rsp), %rax
movq %rax, 0x20(%rbx)
jmp 0x369d3
testq %r15, %r15
je 0x369ae
movq %r15, %rdi
callq 0x2b5f4
cmpb $0x3, (%r15)
jne 0x368f0
movq 0x60(%r15), %r15
cmpb $0xa, (%r15)
jne 0x3690a
movq %r15, %rdi
callq 0x2b5f4
movq %rax, %r15
cmpb $0x3, (%rax)
jne 0x3690a
movq 0x60(%r15), %r15
cmpb $0x9, (%r15)
jne 0x36914
movq 0x60(%r15), %r15
movl (%r15), %eax
cmpb $0x6, %al
je 0x36946
movzbl %al, %eax
cmpl $0x2, %eax
jne 0x369b7
cmpl $0x6, %eax
jne 0x369b7
movq 0x60(%r15), %rax
cmpq 0x2a645(%rip), %rax     # 0x60f80
je 0x369b7
cmpq 0x2a5fc(%rip), %rax     # 0x60f40
je 0x369b7
movq 0x60(%r15), %r15
movq 0x30(%rbx), %r12
testq %r12, %r12
je 0x369c6
movq %r12, %rdi
callq 0x32c63
cmpb $0x3, (%rax)
jne 0x36964
movq 0x60(%rax), %rax
cmpb $0xa, (%rax)
jne 0x3697a
movq %rax, %rdi
callq 0x2b5f4
cmpb $0x3, (%rax)
jne 0x3697a
movq 0x60(%rax), %rax
cmpb $0x9, (%rax)
jne 0x36983
movq 0x60(%rax), %rax
movzbl (%rax), %ecx
cmpq $0x2, %rcx
jne 0x369a2
movq 0x60(%rax), %rdx
cmpq 0x2a5e9(%rip), %rdx     # 0x60f80
je 0x36a16
cmpq 0x2a5a0(%rip), %rdx     # 0x60f40
je 0x36a1d
leaq 0x14297(%rip), %rdx     # 0x4ac40
movl (%rdx,%rcx,4), %ecx
jmp 0x36a22
leaq 0x14bca(%rip), %rsi     # 0x4b57f
jmp 0x369be
leaq 0x14ce1(%rip), %rsi     # 0x4b69f
xorl %r14d, %r14d
movq %rbx, %rdi
jmp 0x369fd
movw $0x3001, (%rbx)         # imm = 0x3001
movq $0x0, 0x20(%rbx)
movl $0x0, 0x28(%rbx)
leaq 0x2ec3f(%rip), %rax     # 0x65620
movq (%rax), %rax
movq %rax, 0x10(%rbx)
jmp 0x36b3b
leaq 0x14c9c(%rip), %r12     # 0x4b690
xorl %r14d, %r14d
movq %rbx, %rdi
movq %r12, %rsi
xorl %eax, %eax
callq 0x11abc
movq %r14, %rax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl $0x1, %ecx
jmp 0x36a22
movl $0x9, %ecx
movl %ecx, %ebp
andl $0x9, %ebp
cmpl $0x1, %ebp
jne 0x36a98
testb $0x4, %cl
je 0x36a58
testb $0x40, %cl
je 0x36a3a
movq 0x60(%rax), %rax
movq %rax, %rdi
callq 0x2386c
movq 0x8(%r12), %rdi
leaq 0x144d5(%rip), %rsi     # 0x4af23
movq %rax, %rdx
xorl %eax, %eax
callq 0x118b4
movb 0x1(%r12), %r13b
leaq 0x2ebbc(%rip), %rax     # 0x65620
movq (%rax), %rsi
movq %r12, %rdi
callq 0x334cd
movq %rax, %r12
movb %r13b, 0x1(%rax)
movl 0x50(%r15), %eax
testl %eax, %eax
movq %r15, 0x10(%rsp)
js 0x36aae
leaq 0x2ec76(%rip), %rcx     # 0x65700
movl (%rcx), %ecx
addl %ecx, %eax
decl %eax
cltd
idivl %ecx
movslq %eax, %r13
jmp 0x36ab5
leaq 0x14c0f(%rip), %rsi     # 0x4b6ae
movq %rbx, %rdi
xorl %eax, %eax
callq 0x11abc
jmp 0x36b32
movq $-0x1, %r13
movq 0x8(%rbx), %r15
xorl %edi, %edi
callq 0x30029
movl (%rax), %ecx
orl $0x1, %ecx
movq %r15, 0x8(%rax)
movq %r13, 0x20(%rax)
leaq 0x35c64(%rip), %rdx     # 0x6c738
movq %rdx, 0x10(%rax)
andl $0xffff0001, %ecx       # imm = 0xFFFF0001
orl $0x3100, %ecx           # imm = 0x3100
movl %ecx, (%rax)
leaq 0x2eb33(%rip), %rsi     # 0x65620
movq (%rsi), %rdx
movq %rdx, 0x10(%rax)
movl %ecx, (%rax)
movl $0xffffff00, %ecx       # imm = 0xFFFFFF00
andl (%rbx), %ecx
orl $0x5, %ecx
movl %ecx, (%rbx)
movq %r12, 0x20(%rbx)
movq %rax, 0x28(%rbx)
movl $0x2a, 0x4(%rbx)
movq (%rsi), %rdx
movq %rdx, 0x10(%rbx)
movl (%rax), %eax
andl (%r12), %eax
andl $0xf400, %eax           # imm = 0xF400
andl $0xffff0005, %ecx       # imm = 0xFFFF0005
orl %eax, %ecx
movl %ecx, (%rbx)
movq 0x10(%rsp), %r15
cmpl $0x1, %ebp
jne 0x36bcd
testq %r14, %r14
je 0x36bbe
xorl %edi, %edi
callq 0x30029
movq %rax, %r12
movaps (%rbx), %xmm0
movaps 0x10(%rbx), %xmm1
movaps 0x20(%rbx), %xmm2
movaps 0x30(%rbx), %xmm3
movaps %xmm3, 0x30(%rax)
movaps %xmm2, 0x20(%rax)
movaps %xmm1, 0x10(%rax)
movaps %xmm0, (%rax)
cmpb $0x1e, (%r14)
jne 0x36b72
movq %r15, 0x20(%r14)
movq %r14, %rdi
callq 0x32c63
testq %rax, %rax
je 0x36bcd
movl $0xffffff00, %eax       # imm = 0xFFFFFF00
andl (%rbx), %eax
orl $0x5, %eax
movl %eax, (%rbx)
movl (%r14), %ecx
andl (%r12), %ecx
andl $0xf400, %ecx           # imm = 0xF400
andl $0xffff0005, %eax       # imm = 0xFFFF0005
orl %ecx, %eax
movl %eax, (%rbx)
movl $0x2b, 0x4(%rbx)
leaq 0x2ea71(%rip), %rax     # 0x65620
movq (%rax), %rax
movq %rax, 0x10(%rbx)
movq %r12, 0x20(%rbx)
movq %r14, 0x28(%rbx)
leaq 0x2ea5b(%rip), %rax     # 0x65620
movq (%rax), %r14
jmp 0x36a04
xorl %r14d, %r14d
jmp 0x36a04