// File: /workspace/github_c_makefile_star2_O3/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, 0x8(%rsp)
movq 0x8(%rdi), %rdi
movl (%rdi), %eax
andl $0x3f, %eax
cmpl $0x12, %eax
jne 0x398fe
cmpl $0x28, 0x10(%rdi)
jne 0x398fe
movq %rsi, %rbx
movq 0x8(%rdi), %rdi
leaq 0x10(%rsp), %r15
movq %r15, %rsi
xorl %edx, %edx
callq 0x1965e
movq %rax, %r14
movq (%r15), %rax
movq 0x18(%rax), %rdx
testq %rdx, %rdx
je 0x397dd
addq $0x12, %rdx
movq (%r14), %rdi
leaq 0x115e5(%rip), %rsi     # 0x4adbb
xorl %eax, %eax
callq 0x11a80
movq (%r14), %r12
movl %r12d, %eax
andl $0x3f, %eax
cmpl $0x12, %eax
jne 0x3991d
cmpl $0x2c, 0x10(%r14)
jne 0x3991d
movl $0x2e, %eax
leaq 0x8(%rsp), %r13
leaq 0x1163e(%rip), %r15     # 0x4ae49
cmpl $0x5a, %eax
jle 0x39844
cmpl $0x5b, %eax
je 0x3988e
cmpl $0x104, %eax            # imm = 0x104
jne 0x3996c
xorl %edi, %edi
callq 0x2f9f5
movq %r12, 0x8(%rax)
movw $0x1e, (%rax)
movl $0x5b, 0x4(%rax)
movq %rax, (%r13)
addq $0x28, %rax
movq %rax, %r13
jmp 0x3984d
cmpl $0x2e, %eax
jne 0x39956
movq 0x8(%r14), %r14
movq (%r14), %rbp
xorl %edi, %edi
callq 0x2f9f5
movq %rax, %r12
movq %rbp, 0x8(%rax)
movw $0x1e, (%rax)
movl $0x2e, 0x4(%rax)
movq (%r14), %rdi
movl %edi, %eax
andl $0x3f, %eax
cmpl $0x3, %eax
jne 0x39946
movq 0x10(%r14), %rax
movq %rax, 0x30(%r12)
movq 0x8(%r14), %r14
jmp 0x398d6
movq 0x8(%r14), %r14
movq (%r14), %rbp
xorl %edi, %edi
callq 0x2f9f5
movq %rax, %r12
movq %rbp, 0x8(%rax)
movw $0x1e, (%rax)
movl $0x5b, 0x4(%rax)
leaq 0x30(%rax), %rsi
movq %r14, %rdi
callq 0x39d79
movq %rax, %rdi
movl $0x5d, %esi
movq %r15, %rdx
callq 0x1950f
movq %rax, %r14
cmpq $0x0, 0x30(%r12)
je 0x39934
movq %r12, (%r13)
movq %r12, %r13
addq $0x28, %r13
movq (%r14), %r12
movl %r12d, %ecx
andl $0x3f, %ecx
xorl %eax, %eax
cmpl $0x12, %ecx
jne 0x3980b
movl 0x10(%r14), %eax
jmp 0x3980b
leaq 0x114e9(%rip), %rdx     # 0x4adee
movl $0x28, %esi
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x1950f
leaq 0x114e1(%rip), %rdx     # 0x4ae05
movq %r14, %rdi
movl $0x2c, %esi
callq 0x1950f
movq %rax, %r14
movq %r14, %rax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x114e7(%rip), %rsi     # 0x4ae34
xorl %eax, %eax
callq 0x11a80
jmp 0x39934
cmpl $0x29, %eax
jne 0x3996c
movq 0x10(%rsp), %rax
movq 0x8(%rsp), %rcx
movq %rax, 0x20(%rcx)
movq %rcx, (%rbx)
leaq 0x114a6(%rip), %rdx     # 0x4ae19
movq %r14, %rdi
movl $0x29, %esi
jmp 0x3992c