// File: /workspace/github_c_makefile_star2_O0/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
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq $0x0, -0x20(%rbp)
leaq -0x20(%rbp), %rax
movq %rax, -0x28(%rbp)
movl $0x2e, -0x34(%rbp)
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rdi
movl $0x28, %esi
callq 0x55c10
cmpl $0x0, %eax
jne 0x56a74
movq -0x10(%rbp), %rdi
movl $0x28, %esi
leaq 0x160a8(%rip), %rdx     # 0x6cb0e
callq 0x22eb0
movq %rax, -0x8(%rbp)
jmp 0x56cd3
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rdi
leaq -0x30(%rbp), %rsi
xorl %eax, %eax
movl %eax, %edx
callq 0x23160
movq %rax, -0x10(%rbp)
movq -0x30(%rbp), %rax
cmpq $0x0, 0x18(%rax)
je 0x56ac1
movq -0x10(%rbp), %rax
movq -0x30(%rbp), %rcx
movq 0x18(%rcx), %rdx
addq $0x12, %rdx
movq (%rax), %rdi
leaq 0x16021(%rip), %rsi     # 0x6cadb
movb $0x0, %al
callq 0x16f90
movq -0x10(%rbp), %rdi
movl $0x2c, %esi
callq 0x55c10
cmpl $0x0, %eax
jne 0x56af2
movq -0x10(%rbp), %rdi
movl $0x2c, %esi
leaq 0x16041(%rip), %rdx     # 0x6cb25
callq 0x22eb0
movq %rax, -0x8(%rbp)
jmp 0x56cd3
jmp 0x56af4
movl -0x34(%rbp), %eax
movl %eax, -0x44(%rbp)
subl $0x29, %eax
je 0x56b29
jmp 0x56b01
movl -0x44(%rbp), %eax
subl $0x2e, %eax
je 0x56b99
jmp 0x56b0f
movl -0x44(%rbp), %eax
subl $0x5b, %eax
je 0x56c15
jmp 0x56b1d
movl -0x44(%rbp), %eax
subl $0x104, %eax            # imm = 0x104
je 0x56b5e
jmp 0x56b40
movq -0x30(%rbp), %rcx
movq -0x20(%rbp), %rax
movq %rcx, 0x20(%rax)
movq -0x20(%rbp), %rcx
movq -0x18(%rbp), %rax
movq %rcx, (%rax)
movq -0x10(%rbp), %rdi
movl $0x29, %esi
leaq 0x15fe9(%rip), %rdx     # 0x6cb39
callq 0x22eb0
movq %rax, -0x8(%rbp)
jmp 0x56cd3
movq -0x10(%rbp), %rax
movq (%rax), %rdi
movl $0x1e, %esi
callq 0x55c50
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
movl $0x5b, 0x4(%rax)
movq -0x40(%rbp), %rcx
movq -0x28(%rbp), %rax
movq %rcx, (%rax)
movq -0x40(%rbp), %rax
addq $0x20, %rax
addq $0x8, %rax
movq %rax, -0x28(%rbp)
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rax
movq (%rax), %rdi
movl $0x1e, %esi
callq 0x55c50
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
movl $0x2e, 0x4(%rax)
movq -0x10(%rbp), %rax
movq (%rax), %rax
andq $0x3f, %rax
cmpl $0x3, %eax
je 0x56bf7
movq -0x10(%rbp), %rax
movq (%rax), %rdi
leaq 0x15f71(%rip), %rsi     # 0x6cb54
movb $0x0, %al
callq 0x16f90
movq -0x10(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x56cd3
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rcx
movq -0x40(%rbp), %rax
movq %rcx, 0x30(%rax)
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x10(%rbp)
jmp 0x56c8a
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rax
movq (%rax), %rdi
movl $0x1e, %esi
callq 0x55c50
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
movl $0x5b, 0x4(%rax)
movq -0x10(%rbp), %rdi
movq -0x40(%rbp), %rsi
addq $0x20, %rsi
addq $0x10, %rsi
callq 0x55cb0
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rdi
movl $0x5d, %esi
leaq 0x15eff(%rip), %rdx     # 0x6cb69
callq 0x22eb0
movq %rax, -0x10(%rbp)
movq -0x40(%rbp), %rax
cmpq $0x0, 0x30(%rax)
jne 0x56c88
movq -0x10(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x56cd3
jmp 0x56c8a
movq -0x40(%rbp), %rcx
movq -0x28(%rbp), %rax
movq %rcx, (%rax)
movq -0x40(%rbp), %rax
addq $0x20, %rax
addq $0x8, %rax
movq %rax, -0x28(%rbp)
movq -0x10(%rbp), %rax
movq (%rax), %rax
andq $0x3f, %rax
cmpl $0x12, %eax
jne 0x56cc1
movq -0x10(%rbp), %rax
movl 0x10(%rax), %eax
movl %eax, -0x48(%rbp)
jmp 0x56cc8
xorl %eax, %eax
movl %eax, -0x48(%rbp)
jmp 0x56cc8
movl -0x48(%rbp), %eax
movl %eax, -0x34(%rbp)
jmp 0x56af4
movq -0x8(%rbp), %rax
addq $0x50, %rsp
popq %rbp
retq
nopl (%rax)