// File: /workspace/github_c_makefile_star2_O0/lucvoo[P]sparse-dev/parse.c
// Function: parse_enum_declaration
static struct token *parse_enum_declaration(struct token *token, struct symbol *parent)
{
	unsigned long long lastval = 0;
	struct symbol *ctype = NULL, *base_type = NULL;
	struct range range = { };
	int mix_bitwise = 0;

	parent->examined = 1;
	parent->ctype.base_type = &int_ctype;
	while (token_type(token) == TOKEN_IDENT) {
		struct expression *expr = NULL;
		struct token *next = token->next;
		struct decl_state ctx = { };
		struct symbol *sym;

		// FIXME: only 'deprecated' should be accepted
		next = handle_attributes(next, &ctx);

		if (match_op(next, '=')) {
			next = constant_expression(next->next, &expr);
			lastval = get_expression_value(expr);
			ctype = &void_ctype;
			if (expr && expr->ctype)
				ctype = expr->ctype;
		} else if (!ctype) {
			ctype = &int_ctype;
		} else if (is_int_type(ctype)) {
			lastval++;
		} else {
			error_die(token->pos, "can't increment the last enum member");
		}

		if (!expr) {
			expr = alloc_expression(token->pos, EXPR_VALUE);
			expr->value = lastval;
			expr->ctype = ctype;
		}

		sym = alloc_symbol(token->pos, SYM_NODE);
		bind_symbol(sym, token->ident, NS_SYMBOL);
		sym->ctype.modifiers &= ~MOD_ADDRESSABLE;
		sym->initializer = expr;
		sym->enum_member = 1;
		sym->ctype.base_type = parent;
		add_ptr_list(&parent->symbol_list, sym);

		if (base_type != &bad_ctype) {
			if (ctype->type == SYM_NODE)
				ctype = ctype->ctype.base_type;
			if (ctype->type == SYM_ENUM) {
				if (ctype == parent)
					ctype = base_type;
				else 
					ctype = ctype->ctype.base_type;
			}
			/*
			 * base_type rules:
			 *  - if all enums are of the same type, then
			 *    the base_type is that type (two first
			 *    cases)
			 *  - if enums are of different types, they
			 *    all have to be integer types, and the
			 *    base type is at least "int_ctype".
			 *  - otherwise the base_type is "bad_ctype".
			 */
			if (!base_type || ctype == &bad_ctype) {
				base_type = ctype;
			} else if (ctype == base_type) {
				/* nothing */
			} else if (is_int_type(base_type) && is_int_type(ctype)) {
				base_type = &int_ctype;
			} else if (is_restricted_type(base_type) != is_restricted_type(ctype)) {
				if (!mix_bitwise++) {
					warning(expr->pos, "mixed bitwiseness");
				}
			} else if (is_restricted_type(base_type) && base_type != ctype) {
				sparse_error(expr->pos, "incompatible restricted type");
				info(expr->pos, "   expected: %s", show_typename(base_type));
				info(expr->pos, "        got: %s", show_typename(ctype));
				base_type = &bad_ctype;
			} else if (base_type != &bad_ctype) {
				sparse_error(token->pos, "bad enum definition");
				base_type = &bad_ctype;
			}
			parent->ctype.base_type = base_type;
		}
		if (is_int_type(base_type)) {
			update_range(&range, lastval, ctype);
		}
		token = next;

		sym->endpos = token->pos;

		if (!match_op(token, ','))
			break;
		token = token->next;
	}
	if (!base_type) {
		sparse_error(token->pos, "empty enum definition");
		base_type = &bad_ctype;
	}
	else if (!is_int_type(base_type))
		;
	else if (type_is_ok(&uint_ctype, range))
		base_type = &uint_ctype;
	else if (type_is_ok(&int_ctype, range))
		base_type = &int_ctype;
	else if (type_is_ok(&ulong_ctype, range))
		base_type = &ulong_ctype;
	else if (type_is_ok(&long_ctype, range))
		base_type = &long_ctype;
	else if (type_is_ok(&ullong_ctype, range))
		base_type = &ullong_ctype;
	else if (type_is_ok(&llong_ctype, range))
		base_type = &llong_ctype;
	else
		base_type = &bad_ctype;
	parent->ctype.base_type = base_type;
	parent->ctype.modifiers |= (base_type->ctype.modifiers & MOD_UNSIGNED);
	parent->examined = 0;

	if (mix_bitwise)
		return token;
	cast_enum_list(parent->symbol_list, base_type);

	return token;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xe0, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq $0x0, -0x20(%rbp)
movq $0x0, -0x28(%rbp)
movq $0x0, -0x30(%rbp)
leaq -0x40(%rbp), %rdi
xorl %esi, %esi
movl $0x10, %edx
callq 0x11130
movl $0x0, -0x44(%rbp)
movq -0x18(%rbp), %rax
movl 0x54(%rax), %ecx
andl $0xfffff7ff, %ecx       # imm = 0xFFFFF7FF
orl $0x800, %ecx            # imm = 0x800
movl %ecx, 0x54(%rax)
movq -0x18(%rbp), %rax
leaq 0x6ba45(%rip), %rcx     # 0x91b18
movq %rcx, 0x60(%rax)
movq -0x10(%rbp), %rax
movq (%rax), %rax
andq $0x3f, %rax
cmpl $0x3, %eax
jne 0x26515
movq $0x0, -0x50(%rbp)
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x58(%rbp)
leaq -0xb0(%rbp), %rdi
xorl %esi, %esi
movl $0x58, %edx
callq 0x11130
movq -0x58(%rbp), %rdi
leaq -0xb0(%rbp), %rsi
callq 0x24630
movq %rax, -0x58(%rbp)
movq -0x58(%rbp), %rdi
movl $0x3d, %esi
callq 0x22f80
cmpl $0x0, %eax
je 0x26186
movq -0x58(%rbp), %rax
movq 0x8(%rax), %rdi
leaq -0x50(%rbp), %rsi
callq 0x56f40
movq %rax, -0x58(%rbp)
movq -0x50(%rbp), %rdi
callq 0x11ff0
movq %rax, -0x20(%rbp)
leaq 0x6b396(%rip), %rax     # 0x914f8
movq %rax, -0x28(%rbp)
cmpq $0x0, -0x50(%rbp)
je 0x26184
movq -0x50(%rbp), %rax
cmpq $0x0, 0x10(%rax)
je 0x26184
movq -0x50(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x28(%rbp)
jmp 0x261cf
cmpq $0x0, -0x28(%rbp)
jne 0x2619a
leaq 0x6b984(%rip), %rax     # 0x91b18
movq %rax, -0x28(%rbp)
jmp 0x261cd
movq -0x28(%rbp), %rdi
callq 0x25ea0
cmpl $0x0, %eax
je 0x261b6
movq -0x20(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x20(%rbp)
jmp 0x261cb
movq -0x10(%rbp), %rax
movq (%rax), %rdi
leaq 0x3ed2a(%rip), %rsi     # 0x64eee
movb $0x0, %al
callq 0x170e0
jmp 0x261cd
jmp 0x261cf
cmpq $0x0, -0x50(%rbp)
jne 0x26203
movq -0x10(%rbp), %rax
movq (%rax), %rdi
movl $0x1, %esi
callq 0x23a70
movq %rax, -0x50(%rbp)
movq -0x20(%rbp), %rcx
movq -0x50(%rbp), %rax
movq %rcx, 0x20(%rax)
movq -0x28(%rbp), %rcx
movq -0x50(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x10(%rbp), %rax
movq (%rax), %rdi
movl $0x3, %esi
callq 0x3f4d0
movq %rax, -0xb8(%rbp)
movq -0xb8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rsi
movl $0x10, %edx
callq 0x40a40
movq -0xb8(%rbp), %rax
movq 0x68(%rax), %rcx
andq $-0x101, %rcx           # imm = 0xFEFF
movq %rcx, 0x68(%rax)
movq -0x50(%rbp), %rcx
movq -0xb8(%rbp), %rax
movq %rcx, 0xb0(%rax)
movq -0xb8(%rbp), %rax
movl (%rax), %ecx
andl $0xffefffff, %ecx       # imm = 0xFFEFFFFF
orl $0x100000, %ecx         # imm = 0x100000
movl %ecx, (%rax)
movq -0x18(%rbp), %rcx
movq -0xb8(%rbp), %rax
movq %rcx, 0x60(%rax)
movq -0x18(%rbp), %rax
addq $0x48, %rax
addq $0x50, %rax
movq %rax, -0xc0(%rbp)
movq -0xc0(%rbp), %rdi
movq -0xb8(%rbp), %rsi
callq 0x31370
movq %rax, -0xc8(%rbp)
leaq 0x6c9e2(%rip), %rax     # 0x92c98
cmpq %rax, -0x30(%rbp)
je 0x264b6
movq -0x28(%rbp), %rax
movl (%rax), %eax
andl $0xff, %eax
cmpl $0x3, %eax
jne 0x262dc
movq -0x28(%rbp), %rax
movq 0x60(%rax), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
movl (%rax), %eax
andl $0xff, %eax
cmpl $0x9, %eax
jne 0x2630e
movq -0x28(%rbp), %rax
cmpq -0x18(%rbp), %rax
jne 0x26300
movq -0x30(%rbp), %rax
movq %rax, -0x28(%rbp)
jmp 0x2630c
movq -0x28(%rbp), %rax
movq 0x60(%rax), %rax
movq %rax, -0x28(%rbp)
jmp 0x2630e
cmpq $0x0, -0x30(%rbp)
je 0x26322
leaq 0x6c97c(%rip), %rax     # 0x92c98
cmpq %rax, -0x28(%rbp)
jne 0x2632f
movq -0x28(%rbp), %rax
movq %rax, -0x30(%rbp)
jmp 0x264aa
movq -0x28(%rbp), %rax
cmpq -0x30(%rbp), %rax
jne 0x2633e
jmp 0x264a8
movq -0x30(%rbp), %rdi
callq 0x25ea0
cmpl $0x0, %eax
je 0x2636a
movq -0x28(%rbp), %rdi
callq 0x25ea0
cmpl $0x0, %eax
je 0x2636a
leaq 0x6b7b7(%rip), %rax     # 0x91b18
movq %rax, -0x30(%rbp)
jmp 0x264a6
movq -0x30(%rbp), %rdi
callq 0x266d0
cmpl $0xd, %eax
sete %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, -0xcc(%rbp)
movq -0x28(%rbp), %rdi
callq 0x266d0
movl %eax, %ecx
movl -0xcc(%rbp), %eax
cmpl $0xd, %ecx
sete %cl
andb $0x1, %cl
movzbl %cl, %ecx
cmpl %ecx, %eax
je 0x263d0
movl -0x44(%rbp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, -0x44(%rbp)
cmpl $0x0, %eax
jne 0x263cb
movq -0x50(%rbp), %rax
movq 0x8(%rax), %rdi
leaq 0x3eb4f(%rip), %rsi     # 0x64f13
movb $0x0, %al
callq 0x16d80
jmp 0x264a4
movq -0x30(%rbp), %rdi
callq 0x266d0
cmpl $0xd, %eax
jne 0x26473
movq -0x30(%rbp), %rax
cmpq -0x28(%rbp), %rax
je 0x26473
movq -0x50(%rbp), %rax
movq 0x8(%rax), %rdi
leaq 0x3eb26(%rip), %rsi     # 0x64f25
movb $0x0, %al
callq 0x16f90
movq -0x50(%rbp), %rax
movq %rax, -0xe0(%rbp)
movq -0x30(%rbp), %rdi
callq 0x33340
movq %rax, %rdx
movq -0xe0(%rbp), %rax
movq 0x8(%rax), %rdi
leaq 0x3eb13(%rip), %rsi     # 0x64f42
movb $0x0, %al
callq 0x16c10
movq -0x50(%rbp), %rax
movq %rax, -0xd8(%rbp)
movq -0x28(%rbp), %rdi
callq 0x33340
movq %rax, %rdx
movq -0xd8(%rbp), %rax
movq 0x8(%rax), %rdi
leaq 0x3eaf3(%rip), %rsi     # 0x64f52
movb $0x0, %al
callq 0x16c10
leaq 0x6c82b(%rip), %rax     # 0x92c98
movq %rax, -0x30(%rbp)
jmp 0x264a2
leaq 0x6c81e(%rip), %rax     # 0x92c98
cmpq %rax, -0x30(%rbp)
je 0x264a0
movq -0x10(%rbp), %rax
movq (%rax), %rdi
leaq 0x3ead4(%rip), %rsi     # 0x64f62
movb $0x0, %al
callq 0x16f90
leaq 0x6c7fc(%rip), %rax     # 0x92c98
movq %rax, -0x30(%rbp)
jmp 0x264a2
jmp 0x264a4
jmp 0x264a6
jmp 0x264a8
jmp 0x264aa
movq -0x30(%rbp), %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x60(%rax)
movq -0x30(%rbp), %rdi
callq 0x25ea0
cmpl $0x0, %eax
je 0x264d5
movq -0x20(%rbp), %rsi
movq -0x28(%rbp), %rdx
leaq -0x40(%rbp), %rdi
callq 0x26720
movq -0x58(%rbp), %rax
movq %rax, -0x10(%rbp)
movq -0xb8(%rbp), %rax
movq -0x10(%rbp), %rcx
movq (%rcx), %rcx
movq %rcx, 0xc(%rax)
movq -0x10(%rbp), %rdi
movl $0x2c, %esi
callq 0x22f80
cmpl $0x0, %eax
jne 0x26504
jmp 0x26515
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x10(%rbp)
jmp 0x260d7
cmpq $0x0, -0x30(%rbp)
jne 0x26541
movq -0x10(%rbp), %rax
movq (%rax), %rdi
leaq 0x3ea4c(%rip), %rsi     # 0x64f76
movb $0x0, %al
callq 0x16f90
leaq 0x6c760(%rip), %rax     # 0x92c98
movq %rax, -0x30(%rbp)
jmp 0x2665a
movq -0x30(%rbp), %rdi
callq 0x25ea0
cmpl $0x0, %eax
jne 0x26554
jmp 0x26658
movq -0x40(%rbp), %rsi
movq -0x38(%rbp), %rdx
leaq 0x6b775(%rip), %rdi     # 0x91cd8
callq 0x26790
cmpl $0x0, %eax
je 0x2657d
leaq 0x6b764(%rip), %rax     # 0x91cd8
movq %rax, -0x30(%rbp)
jmp 0x26656
movq -0x40(%rbp), %rsi
movq -0x38(%rbp), %rdx
leaq 0x6b58c(%rip), %rdi     # 0x91b18
callq 0x26790
cmpl $0x0, %eax
je 0x265a6
leaq 0x6b57b(%rip), %rax     # 0x91b18
movq %rax, -0x30(%rbp)
jmp 0x26654
movq -0x40(%rbp), %rsi
movq -0x38(%rbp), %rdx
leaq 0x6b9c3(%rip), %rdi     # 0x91f78
callq 0x26790
cmpl $0x0, %eax
je 0x265cf
leaq 0x6b9b2(%rip), %rax     # 0x91f78
movq %rax, -0x30(%rbp)
jmp 0x26652
movq -0x40(%rbp), %rsi
movq -0x38(%rbp), %rdx
leaq 0x6b7da(%rip), %rdi     # 0x91db8
callq 0x26790
cmpl $0x0, %eax
je 0x265f5
leaq 0x6b7c9(%rip), %rax     # 0x91db8
movq %rax, -0x30(%rbp)
jmp 0x26650
movq -0x40(%rbp), %rsi
movq -0x38(%rbp), %rdx
leaq 0x6bc14(%rip), %rdi     # 0x92218
callq 0x26790
cmpl $0x0, %eax
je 0x2661b
leaq 0x6bc03(%rip), %rax     # 0x92218
movq %rax, -0x30(%rbp)
jmp 0x2664e
movq -0x40(%rbp), %rsi
movq -0x38(%rbp), %rdx
leaq 0x6ba2e(%rip), %rdi     # 0x92058
callq 0x26790
cmpl $0x0, %eax
je 0x26641
leaq 0x6ba1d(%rip), %rax     # 0x92058
movq %rax, -0x30(%rbp)
jmp 0x2664c
leaq 0x6c650(%rip), %rax     # 0x92c98
movq %rax, -0x30(%rbp)
jmp 0x2664e
jmp 0x26650
jmp 0x26652
jmp 0x26654
jmp 0x26656
jmp 0x26658
jmp 0x2665a
movq -0x30(%rbp), %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x60(%rax)
movq -0x30(%rbp), %rax
movq 0x68(%rax), %rcx
andq $0x4000, %rcx           # imm = 0x4000
movq -0x18(%rbp), %rax
orq 0x68(%rax), %rcx
movq %rcx, 0x68(%rax)
movq -0x18(%rbp), %rax
movl 0x54(%rax), %ecx
andl $0xfffff7ff, %ecx       # imm = 0xFFFFF7FF
orl $0x0, %ecx
movl %ecx, 0x54(%rax)
cmpl $0x0, -0x44(%rbp)
je 0x266a4
movq -0x10(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x266c0
movq -0x18(%rbp), %rax
movq 0x98(%rax), %rdi
movq -0x30(%rbp), %rsi
callq 0x26840
movq -0x10(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0xe0, %rsp
popq %rbp
retq
nopl (%rax)