// File: /workspace/github_c_makefile_star2_O1/lucvoo[P]sparse-dev/expression.c
// Function: builtin_offsetof_expr
static struct token *builtin_offsetof_expr(struct token *token,
					   struct expression **tree)
{
	struct expression *expr = NULL;
	struct expression **p = &expr;
	struct symbol *sym;
	int op = '.';

	token = token->next;
	if (!match_op(token, '('))
		return expect(token, '(', "after __builtin_offset");

	token = token->next;
	token = typename(token, &sym, NULL);
	if (sym->ident)
		sparse_error(token->pos,
			     "type expression should not include identifier "
			     "\"%s\"", sym->ident->name);

	if (!match_op(token, ','))
		return expect(token, ',', "in __builtin_offset");

	while (1) {
		struct expression *e;
		switch (op) {
		case ')':
			expr->in = sym;
			*tree = expr;
		default:
			return expect(token, ')', "at end of __builtin_offset");
		case SPECIAL_DEREFERENCE:
			e = alloc_expression(token->pos, EXPR_OFFSETOF);
			e->op = '[';
			*p = e;
			p = &e->down;
			/* fall through */
		case '.':
			token = token->next;
			e = alloc_expression(token->pos, EXPR_OFFSETOF);
			e->op = '.';
			if (token_type(token) != TOKEN_IDENT) {
				sparse_error(token->pos, "Expected member name");
				return token;
			}
			e->ident = token->ident;
			token = token->next;
			break;
		case '[':
			token = token->next;
			e = alloc_expression(token->pos, EXPR_OFFSETOF);
			e->op = '[';
			token = parse_expression(token, &e->index);
			token = expect(token, ']',
					"at end of array dereference");
			if (!e->index)
				return token;
		}
		*p = e;
		p = &e->down;
		op = token_type(token) == TOKEN_SPECIAL ? token->special : 0;
	}
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq $0x0, (%rsp)
movq 0x8(%rdi), %rdi
movl (%rdi), %eax
andl $0x3f, %eax
cmpl $0x12, %eax
jne 0x3a571
cmpl $0x28, 0x10(%rdi)
jne 0x3a571
movq %rsi, %rbx
movq 0x8(%rdi), %rdi
leaq 0x10(%rsp), %r15
movq %r15, %rsi
xorl %edx, %edx
callq 0x19726
movq %rax, %r14
movq (%r15), %rax
movq 0x18(%rax), %rdx
testq %rdx, %rdx
je 0x3a3c7
addq $0x12, %rdx
movq (%r14), %rdi
leaq 0x11a8b(%rip), %rsi     # 0x4be4b
xorl %eax, %eax
callq 0x11a38
movl (%r14), %eax
andl $0x3f, %eax
cmpl $0x12, %eax
jne 0x3a590
cmpl $0x2c, 0x10(%r14)
jne 0x3a590
movq %rbx, 0x8(%rsp)
movl $0x2e, %r15d
movq %rsp, %r13
cmpl $0x5a, %r15d
jg 0x3a40a
cmpl $0x29, %r15d
je 0x3a4af
cmpl $0x2e, %r15d
je 0x3a44e
jmp 0x3a4c4
cmpl $0x5b, %r15d
je 0x3a4e2
cmpl $0x104, %r15d           # imm = 0x104
jne 0x3a4c4
movq (%r14), %rbx
xorl %edi, %edi
callq 0x30029
movl (%rax), %ecx
orl $0x1e, %ecx
movq %rbx, 0x8(%rax)
andl $0xffff001e, %ecx       # imm = 0xFFFF001E
movl %ecx, (%rax)
movl $0x5b, 0x4(%rax)
movq %rax, (%r13)
addq $0x28, %rax
movq %rax, %r13
movq 0x8(%r14), %r14
movq (%r14), %rbx
xorl %edi, %edi
callq 0x30029
movq %rax, %r12
movl (%rax), %eax
orl $0x1e, %eax
movq %rbx, 0x8(%r12)
andl $0xffff001e, %eax       # imm = 0xFFFF001E
movl %eax, (%r12)
movl $0x2e, 0x4(%r12)
movq (%r14), %rdi
movl %edi, %eax
andl $0x3f, %eax
cmpl $0x3, %eax
jne 0x3a49a
movq 0x10(%r14), %rax
movq %rax, 0x30(%r12)
movq 0x8(%r14), %r14
jmp 0x3a53d
xorl %ebx, %ebx
leaq 0x11a21(%rip), %rsi     # 0x4bec4
xorl %eax, %eax
callq 0x11a38
jmp 0x3a564
movq 0x10(%rsp), %rax
movq (%rsp), %rcx
movq %rax, 0x20(%rcx)
movq 0x8(%rsp), %rax
movq %rcx, (%rax)
movq %r14, %rdi
movl $0x29, %esi
leaq 0x119d6(%rip), %rdx     # 0x4bea9
callq 0x195d7
movq %rax, %rbp
xorl %ebx, %ebx
jmp 0x3a567
movq 0x8(%r14), %r14
movq (%r14), %r15
xorl %ebx, %ebx
xorl %edi, %edi
callq 0x30029
movq %rax, %r12
movl (%rax), %eax
orl $0x1e, %eax
movq %r15, 0x8(%r12)
andl $0xffff001e, %eax       # imm = 0xFFFF001E
movl %eax, (%r12)
movl $0x5b, 0x4(%r12)
leaq 0x30(%r12), %rsi
movq %r14, %rdi
callq 0x3a9cd
movq %rax, %rdi
movl $0x5d, %esi
leaq 0x119ac(%rip), %rdx     # 0x4bed9
callq 0x195d7
movq %rax, %r14
cmpq $0x0, 0x30(%r12)
je 0x3a55e
movq %r12, (%r13)
movq %r12, %r13
addq $0x28, %r13
movl (%r14), %eax
andl $0x3f, %eax
movb $0x1, %bl
xorl %r15d, %r15d
cmpl $0x12, %eax
jne 0x3a567
movl 0x10(%r14), %r15d
jmp 0x3a567
movl $0x5b, %r15d
movq %r14, %rbp
testb %bl, %bl
jne 0x3a3ef
jmp 0x3a5a7
leaq 0x11906(%rip), %rdx     # 0x4be7e
movl $0x28, %esi
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x195d7
leaq 0x118fe(%rip), %rdx     # 0x4be95
movq %r14, %rdi
movl $0x2c, %esi
callq 0x195d7
movq %rax, %rbp
movq %rbp, %rax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq