// File: /workspace/github_c_makefile_star2_O1/lucvoo[P]sparse-dev/expression.c
// Function: primary_expression
struct token *primary_expression(struct token *token, struct expression **tree)
{
	struct expression *expr = NULL;

	switch (token_type(token)) {
	case TOKEN_CHAR ... TOKEN_WIDE_CHAR_EMBEDDED_3:
		expr = alloc_expression(token->pos, EXPR_VALUE);
		expr->flags = CEF_SET_CHAR;
		get_char_constant(token, &expr->value);

		// TODO: handle 'u8', 'u' & 'U' prefixes.
		if (token_type(token) < TOKEN_WIDE_CHAR) {
			expr->ctype = &char_ctype;
			cast_value(expr, &int_ctype, expr);
		} else {
			expr->ctype = wchar_ctype;
		}
		token = token->next;
		break;

	case TOKEN_NUMBER:
		expr = alloc_expression(token->pos, EXPR_VALUE);
		get_number_value(expr, token); /* will see if it's an integer */
		token = token->next;
		break;

	case TOKEN_ZERO_IDENT: {
		expr = alloc_expression(token->pos, EXPR_SYMBOL);
		expr->flags = CEF_SET_INT;
		expr->ctype = &int_ctype;
		expr->symbol = &zero_int;
		expr->symbol_name = token->ident;
		token = token->next;
		break;
	}

	case TOKEN_IDENT: {
		struct symbol *sym = lookup_symbol(token->ident, NS_SYMBOL | NS_TYPEDEF);
		struct token *next = token->next;

		if (!sym) {
			sym = handle_func(token);
			if (token->ident == &__builtin_types_compatible_p_ident) {
				token = builtin_types_compatible_p_expr(token, &expr);
				break;
			}
			if (token->ident == &__builtin_offsetof_ident) {
				token = builtin_offsetof_expr(token, &expr);
				break;
			}
			if (token->ident == &_Generic_ident) {
				token = generic_selection(token->next, &expr);
				break;
			}
		} else if (sym->enum_member) {
			expr = alloc_expression(token->pos, EXPR_VALUE);
			*expr = *sym->initializer;
			/* we want the right position reported, thus the copy */
			expr->pos = token->pos;
			expr->flags = CEF_SET_ENUM;
			token = next;
			break;
		}

		expr = alloc_expression(token->pos, EXPR_SYMBOL);

		/*
		 * We support types as real first-class citizens, with type
		 * comparisons etc:
		 *
		 *	if (typeof(a) == int) ..
		 */
		if (sym && sym->namespace == NS_TYPEDEF) {
			sparse_error(token->pos, "typename in expression");
			sym = NULL;
		}
		expr->symbol_name = token->ident;
		expr->symbol = sym;

		/*
		 * A pointer to an lvalue designating a static storage
		 * duration object is an address constant [6.6(9)].
		 */
		if (sym && (sym->ctype.modifiers & (MOD_TOPLEVEL | MOD_STATIC)))
			expr->flags = CEF_ADDR;

		token = next;
		break;
	}

	case TOKEN_STRING:
	case TOKEN_WIDE_STRING:
		expr = alloc_expression(token->pos, EXPR_STRING);
		token = get_string_constant(token, expr);
		break;

	case TOKEN_SPECIAL:
		if (token->special == '(') {
			expr = alloc_expression(token->pos, EXPR_PREOP);
			expr->op = '(';
			token = parens_expression(token, &expr->unop, "in expression");
			break;
		}
		if (token->special == '[' && lookup_type(token->next)) {
			expr = alloc_expression(token->pos, EXPR_TYPE);
			token = typename(token->next, &expr->symbol, NULL);
			token = expect(token, ']', "in type expression");
			break;
		}
			
	default:
		;
	}
	*tree = expr;
	return token;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %rsi, %rbx
movq %rdi, %r14
movq $0x0, (%rsp)
movq (%rdi), %r12
movl %r12d, %eax
andl $0x3f, %eax
addl $-0x3, %eax
cmpl $0xf, %eax
ja 0x39fcb
leaq 0x121a7(%rip), %rcx     # 0x4bb70
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
xorl %edi, %edi
callq 0x30029
movq %rax, %r15
movl (%rax), %eax
orl $0x1, %eax
movq %r12, 0x8(%r15)
andl $0xffff0001, %eax       # imm = 0xFFFF0001
movl %eax, (%r15)
movq %r15, (%rsp)
orl $0x3800, %eax           # imm = 0x3800
movl %eax, (%r15)
leaq 0x20(%r15), %rsi
movq %r14, %rdi
callq 0x4006c
movl (%r14), %eax
andl $0x3f, %eax
cmpl $0xa, %eax
ja 0x39a2f
leaq 0x32001(%rip), %rax     # 0x6ba18
movq %rax, 0x10(%r15)
leaq 0x32d16(%rip), %rsi     # 0x6c738
movq %r15, %rdi
movq %r15, %rdx
callq 0xea84
jmp 0x39a3d
leaq 0x2bc2a(%rip), %rax     # 0x65660
movq (%rax), %rax
movq %rax, 0x10(%r15)
movq 0x8(%r14), %r15
movq (%rsp), %rax
movq %rax, (%rbx)
movq %r15, %rax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
xorl %edi, %edi
callq 0x30029
movl (%rax), %ecx
orl $0x2, %ecx
movq %r12, 0x8(%rax)
andl $0xffff0002, %ecx       # imm = 0xFFFF0002
movl %ecx, (%rax)
movq %rax, (%rsp)
movq %r14, %rdi
movq %rax, %rsi
callq 0x4032d
movq %rax, %r15
jmp 0x39a41
xorl %edi, %edi
callq 0x30029
movq %rax, %r15
movl (%rax), %eax
orl $0x1, %eax
movq %r12, 0x8(%r15)
andl $0xffff0001, %eax       # imm = 0xFFFF0001
movl %eax, (%r15)
movq %r15, (%rsp)
movq 0x10(%r14), %r13
callq 0xe070
movq %rax, %rbp
movl $0x0, (%rax)
cmpb $0x30, (%r13)
jne 0x39c01
callq 0xe2f0
movq (%rax), %rax
movzbl 0x1(%r13), %ecx
cmpl $0x62, (%rax,%rcx,4)
jne 0x39c01
leaq 0x2(%r13), %rdi
leaq 0x10(%rsp), %rsi
movl $0x2, %edx
jmp 0x39c0b
movq 0x10(%r14), %rdi
movl $0x12, %esi
callq 0x2b511
movq 0x8(%r14), %r15
testq %rax, %rax
je 0x39dda
movq %rax, %r12
testb $0x10, 0x2(%rax)
je 0x3a001
movq (%r14), %r13
xorl %edi, %edi
callq 0x30029
movl (%rax), %ecx
orl $0x1, %ecx
movq %r13, 0x8(%rax)
andl $0xffff0001, %ecx       # imm = 0xFFFF0001
movl %ecx, (%rax)
movq %rax, (%rsp)
movq 0xb0(%r12), %rcx
movaps (%rcx), %xmm0
movaps 0x10(%rcx), %xmm1
movaps 0x20(%rcx), %xmm2
movaps 0x30(%rcx), %xmm3
movaps %xmm0, (%rax)
movaps %xmm1, 0x10(%rax)
movaps %xmm2, 0x20(%rax)
movaps %xmm3, 0x30(%rax)
movq (%r14), %rcx
movq %rcx, 0x8(%rax)
movb $0x34, 0x1(%rax)
jmp 0x39a41
xorl %edi, %edi
callq 0x30029
movl (%rax), %ecx
orl $0x3, %ecx
movq %r12, 0x8(%rax)
andl $0xffff0003, %ecx       # imm = 0xFFFF0003
movl %ecx, (%rax)
movq %rax, (%rsp)
orl $0x3100, %ecx           # imm = 0x3100
movl %ecx, (%rax)
leaq 0x32ba4(%rip), %rcx     # 0x6c738
movq %rcx, 0x10(%rax)
leaq 0x352f9(%rip), %rcx     # 0x6ee98
movq %rcx, 0x20(%rax)
movq 0x10(%r14), %rcx
movq %rcx, 0x28(%rax)
jmp 0x39a3d
movl 0x10(%r14), %eax
cmpl $0x5b, %eax
je 0x39f77
cmpl $0x28, %eax
jne 0x39fcb
xorl %edi, %edi
callq 0x30029
movl (%rax), %ecx
orl $0x9, %ecx
movq %r12, 0x8(%rax)
andl $0xffff0009, %ecx       # imm = 0xFFFF0009
movl %ecx, (%rax)
movq %rax, (%rsp)
movl $0x28, 0x4(%rax)
leaq 0x20(%rax), %rsi
leaq 0x12054(%rip), %rdx     # 0x4bc48
movq %r14, %rdi
callq 0x39869
jmp 0x39a81
leaq 0x10(%rsp), %rsi
movq %r13, %rdi
xorl %edx, %edx
callq 0xe1a0
movq %rax, %r12
movq 0x10(%rsp), %r8
cmpq %r13, %r8
je 0x39d73
movb $0x1, %cl
cmpq $-0x1, %r12
jne 0x39c30
cmpl $0x22, (%rbp)
setne %cl
xorl %eax, %eax
xorl %edx, %edx
leaq 0x1(%r8), %rsi
movq %rsi, 0x10(%rsp)
movzbl (%r8), %r9d
testl %r9d, %r9d
je 0x39c70
movl %r9d, %r10d
andl $-0x21, %r10d
cmpl $0x4c, %r10d
je 0x39c77
movl $0x2, %edi
cmpl $0x55, %r10d
jne 0x39c80
xorl %edi, %edi
testl %eax, %eax
setne %dil
leal (%rdi,%rdi,4), %edi
movl $0x1, %eax
jmp 0x39c80
movl $0x4, %edi
jmp 0x39c80
movl $0x5, %edi
testl %edx, %edx
je 0x39c89
movq %rsi, %r8
testl %edi, %edi
je 0x39c34
jmp 0x39ca8
xorl %edi, %edi
movl $0x1, %edx
cmpb %r9b, (%rsi)
jne 0x39c80
addq $0x2, %r8
movq %r8, 0x10(%rsp)
movl $0x2, %edx
movq %r8, %rsi
jmp 0x39c80
cmpl $0x2, %edi
je 0x39d73
cmpl $0x5, %edi
je 0x39da5
cmpl $0x4, %edi
jne 0x39a3d
testb %cl, %cl
je 0x3a26b
cmpb $0x30, (%r13)
setne %cl
testl %eax, %eax
sete %sil
andb %cl, %sil
xorl %edi, %edi
testl %edx, %edx
jne 0x39d0a
leaq 0x2ba1f(%rip), %rcx     # 0x65708
movl (%rcx), %ecx
decl %ecx
movq %r12, %r8
shrq %cl, %r8
movl $0x1, %edi
movl $0x1, %edx
testq $-0x2, %r8
je 0x3a218
cmpl $0x1, %edx
jg 0x3a0d0
leaq 0x2b9f2(%rip), %rcx     # 0x6570c
movl (%rcx), %ecx
decl %ecx
movq %r12, %rdx
shrq %cl, %rdx
movl $0x1, %r10d
testq $-0x2, %rdx
jne 0x3a0d3
leaq 0x7b8f(%rip), %r9       # 0x418cd
leaq 0xdc9e(%rip), %r8       # 0x479e3
btq %rcx, %r12
jae 0x3a246
movl $0x1, %r13d
movl $0x3, %r10d
movl %edi, %ebp
movl $0x1, 0x8(%rsp)
testb %sil, %sil
jne 0x3a0d3
jmp 0x3a15c
leaq 0x10(%rsp), %r12
movq %r13, %rdi
movq %r12, %rsi
callq 0x31485
fstpt 0x20(%r15)
movq (%r12), %rax
cmpq %rax, %r13
je 0x39da5
movzbl (%rax), %ecx
testl %ecx, %ecx
je 0x3a202
cmpb $0x0, 0x1(%rax)
je 0x3a09d
movq %r14, %rdi
callq 0x2e5c0
movq 0x8(%r15), %rdi
leaq 0x12007(%rip), %rsi     # 0x4bdbf
movq %rax, %rdx
xorl %eax, %eax
callq 0x11a38
movb $0x1, (%r15)
movq $0x0, 0x20(%r15)
leaq 0x32963(%rip), %rax     # 0x6c738
jmp 0x39a39
movq 0x10(%r14), %rbp
cmpq 0x2713b(%rip), %rbp     # 0x60f20
je 0x39dfd
cmpq 0x270fa(%rip), %rbp     # 0x60ee8
je 0x39dfd
cmpq 0x270d9(%rip), %rbp     # 0x60ed0
jne 0x39fd3
leaq 0x5716c(%rip), %rax     # 0x90f70
movq (%rax), %rax
testq %rax, %rax
je 0x39fd3
cmpq $0x0, 0x18(%rax)
je 0x39fd3
movq (%r14), %rdi
movl $0x6, %esi
callq 0x2b547
movq %rax, %r13
leaq 0x31be6(%rip), %rcx     # 0x6ba18
movq %rcx, 0x60(%rax)
movl $0x1, %ecx
movq %rcx, 0x70(%rax)
movq (%r14), %rcx
movq %rcx, 0xc(%rax)
movq %rax, 0x18(%rsp)
movq (%r14), %rdi
movl $0x3, %esi
callq 0x2b547
movq %rax, %r12
movq %r13, 0x60(%rax)
movl $0x1, %eax
movq %rax, 0x70(%r12)
movq $0x4, 0x68(%r12)
movq (%r14), %rax
movq %rax, 0xc(%r12)
leaq 0x2af0f(%rip), %rax     # 0x64d90
movq (%rax), %rcx
movq %r12, %rdi
movq %rbp, %rsi
movl $0x10, %edx
callq 0x2c259
leaq 0x570d5(%rip), %rax     # 0x90f70
movq (%rax), %rax
movq 0x18(%rax), %rax
movzbl 0x10(%rax), %r13d
leaq 0x1(%r13), %rdi
movq %rdi, 0x8(%rsp)
callq 0x300ef
movq %rax, %rbp
leaq 0x4(%rax), %rdi
leaq 0x570ad(%rip), %rax     # 0x90f70
movq (%rax), %rax
movq 0x18(%rax), %rsi
addq $0x12, %rsi
movq %r13, %rdx
callq 0xe1e0
movb $0x0, 0x4(%rbp,%r13)
movl $0x80000000, %eax       # imm = 0x80000000
andl (%rbp), %eax
addl 0x8(%rsp), %eax
movl %eax, (%rbp)
movq (%r14), %r13
xorl %edi, %edi
callq 0x30029
movl (%rax), %ecx
orl $0x2, %ecx
movq %r13, 0x8(%rax)
andl $0xffff0002, %ecx       # imm = 0xFFFF0002
movl %ecx, (%rax)
movq %rax, 0xb0(%r12)
movq %rbp, 0x28(%rax)
movq 0xb0(%r12), %rax
movq %r12, 0x10(%rax)
movq (%r14), %r13
xorl %edi, %edi
callq 0x30029
movl (%rax), %ecx
orl $0x1, %ecx
movq %r13, 0x8(%rax)
movq 0x8(%rsp), %rsi
movq %rsi, 0x20(%rax)
leaq 0x327f7(%rip), %rdx     # 0x6c738
movq %rdx, 0x10(%rax)
andl $0xffff0001, %ecx       # imm = 0xFFFF0001
orl $0x3100, %ecx           # imm = 0x3100
movl %ecx, (%rax)
movq %rax, 0x58(%r12)
movq 0x18(%rsp), %rcx
movq %rax, 0x58(%rcx)
leaq 0x2b798(%rip), %rax     # 0x65700
movl (%rax), %eax
imull %esi, %eax
movl %eax, 0x50(%rcx)
movl %eax, 0x50(%r12)
jmp 0x39fd6
movq 0x8(%r14), %rdi
callq 0x3a771
testl %eax, %eax
je 0x39fcb
movq (%r14), %r15
xorl %edi, %edi
callq 0x30029
movl (%rax), %ecx
orl $0x4, %ecx
movq %r15, 0x8(%rax)
andl $0xffff0004, %ecx       # imm = 0xFFFF0004
movl %ecx, (%rax)
movq %rax, (%rsp)
movq 0x8(%r14), %rdi
leaq 0x20(%rax), %rsi
xorl %edx, %edx
callq 0x19726
leaq 0x11c9d(%rip), %rdx     # 0x4bc56
movq %rax, %rdi
movl $0x5d, %esi
callq 0x195d7
jmp 0x39a81
movq %r14, %r15
jmp 0x39a41
xorl %r12d, %r12d
movq 0x10(%r14), %rax
cmpq 0x26f77(%rip), %rax     # 0x60f58
je 0x3a07d
cmpq 0x26f3a(%rip), %rax     # 0x60f28
je 0x3a08d
cmpq 0x26fdd(%rip), %rax     # 0x60fd8
je 0x3a13a
movq (%r14), %rbp
xorl %edi, %edi
callq 0x30029
movq %rax, %r13
movl (%rax), %eax
orl $0x3, %eax
movq %rbp, 0x8(%r13)
andl $0xffff0003, %eax       # imm = 0xFFFF0003
movl %eax, (%r13)
movq %r13, (%rsp)
testq %r12, %r12
je 0x3a04f
movl $0x1ff00, %eax          # imm = 0x1FF00
andl (%r12), %eax
cmpl $0x200, %eax            # imm = 0x200
jne 0x3a052
movq (%r14), %rdi
leaq 0x11bfc(%rip), %rsi     # 0x4bc3f
xorl %r12d, %r12d
xorl %eax, %eax
callq 0x11a38
jmp 0x3a052
xorl %r12d, %r12d
movq 0x10(%r14), %rax
movq %rax, 0x28(%r13)
movq %r12, 0x20(%r13)
testq %r12, %r12
je 0x39a41
testb $0x14, 0x68(%r12)
je 0x39a41
movb $0x40, 0x1(%r13)
jmp 0x39a41
movq %rsp, %rsi
movq %r14, %rdi
callq 0x3a288
jmp 0x39a81
movq %rsp, %rsi
movq %r14, %rdi
callq 0x3a35b
jmp 0x39a81
leaq 0x33114(%rip), %rax     # 0x6d1b8
cmpl $0x4b, %ecx
jle 0x3a1f4
cmpl $0x6c, %ecx
je 0x3a0c4
cmpl $0x66, %ecx
je 0x3a209
cmpl $0x4c, %ecx
jne 0x39da5
leaq 0x332ad(%rip), %rax     # 0x6d378
jmp 0x3a209
movl %edi, %r10d
leaq 0x2b636(%rip), %rcx     # 0x65710
movl (%rcx), %ecx
decl %ecx
movq %r12, %rdx
shrq %cl, %rdx
testq $-0x2, %rdx
jne 0x3a26b
leaq 0xd8eb(%rip), %r8       # 0x479e3
btq %rcx, %r12
jae 0x3a14b
movl $0x2, 0x8(%rsp)
movl $0x1, %r13d
testb %sil, %sil
je 0x3a156
movq %r14, %rdi
movl %r10d, %ebp
callq 0x2e5c0
movq 0x8(%r15), %rdi
leaq 0x11b6b(%rip), %rsi     # 0x4bc92
movq %rax, %rdx
xorl %eax, %eax
callq 0x118b4
leaq 0xd8ab(%rip), %r8       # 0x479e3
jmp 0x3a159
movq 0x8(%r14), %rdi
movq %rsp, %rsi
callq 0x3a5b9
jmp 0x39a81
movl $0x2, 0x8(%rsp)
movl %eax, %r13d
movl %r10d, %ebp
movq %r8, %r9
testl %ebp, %ebp
je 0x3a1b2
leaq 0x2dc89(%rip), %rax     # 0x67df0
cmpl $0x0, (%rax)
je 0x3a1b2
movq %r14, %rdi
movq %r8, 0x20(%rsp)
movq %r9, 0x18(%rsp)
callq 0x2e5c0
testl %r13d, %r13d
leaq 0x7745(%rip), %rdx      # 0x418cd
leaq 0x11b52(%rip), %rcx     # 0x4bce1
cmoveq %rdx, %rcx
movq 0x8(%r15), %rdi
leaq 0x11b21(%rip), %rsi     # 0x4bcbf
movq %rax, %rdx
movq 0x20(%rsp), %r8
movq 0x18(%rsp), %r9
xorl %eax, %eax
callq 0x118b4
testb $0x2, %bpl
je 0x3a1d5
movq %r14, %rdi
callq 0x2e5c0
movq 0x8(%r15), %rdi
leaq 0x11b20(%rip), %rsi     # 0x4bceb
movq %rax, %rdx
xorl %eax, %eax
callq 0x118b4
movw $0x3101, (%r15)         # imm = 0x3101
movl 0x8(%rsp), %edi
movl %r13d, %esi
callq 0x19709
movq %rax, 0x10(%r15)
movq %r12, 0x20(%r15)
jmp 0x39a3d
testl %ecx, %ecx
je 0x3a202
cmpl $0x46, %ecx
je 0x3a209
jmp 0x39da5
leaq 0x3308f(%rip), %rax     # 0x6d298
movq %rax, 0x10(%r15)
movw $0x221c, (%r15)         # imm = 0x221C
jmp 0x39a3d
leaq 0x76ae(%rip), %r8       # 0x418cd
xorl %ebp, %ebp
btq %rcx, %r12
jae 0x3a258
movl $0x1, %r13d
movq %r8, %r9
movl $0x0, 0x8(%rsp)
testb %sil, %sil
jne 0x39d0a
jmp 0x3a15c
movl $0x1, 0x8(%rsp)
movl %eax, %r13d
movl %edi, %ebp
jmp 0x3a15c
movl %eax, %r13d
movq %r8, %r9
movl $0x0, 0x8(%rsp)
jmp 0x3a15c
movq %r14, %rdi
callq 0x2e5c0
movq 0x8(%r15), %rdi
leaq 0x11b0e(%rip), %rsi     # 0x4bd8c
movq %rax, %rdx
xorl %eax, %eax
callq 0x11b54