// File: /workspace/github_c_makefile_star2_O0/hsjoihs[P]c-compiler/parse_expression.c
// Function: parse_unary_expression
static struct UntypedExpr
parse_unary_expression(const struct Token **ptr_tokvec)
{
	const struct Token *tokvec = *ptr_tokvec;

	if (tokvec[0].kind == OP_NOT || tokvec[0].kind == OP_TILDA ||
	    tokvec[0].kind == OP_PLUS || tokvec[0].kind == OP_MINUS ||
	    tokvec[0].kind == OP_ASTERISK || tokvec[0].kind == OP_AND) {
		enum TokenKind kind = tokvec[0].kind;
		++tokvec;

		const struct UntypedExpr expr = parse_cast_expression(&tokvec);

		const struct UntypedExpr new_expr = unary_op_untyped(&expr, kind);

		*ptr_tokvec = tokvec;
		return new_expr;
	} else if (tokvec[0].kind == RES_SIZEOF && tokvec[1].kind == LEFT_PAREN &&
	           can_start_a_type(tokvec + 2)) {
		tokvec += 2;
		struct Type type = parse_type_name(&tokvec);
		expect_and_consume(&tokvec, RIGHT_PAREN,
		                   "closing parenthesis of sizeof(typename)");

		struct UntypedExpr expr;
		expr.category = SIZEOF_TYPE;
		expr.operand_of_sizeof_or_alignof = type;
		*ptr_tokvec = tokvec;
		return expr;
	} else if (tokvec[0].kind == OP_PLUS_PLUS ||
	           tokvec[0].kind == OP_MINUS_MINUS ||
	           tokvec[0].kind == RES_SIZEOF) {
		enum TokenKind opkind = tokvec[0].kind;
		++tokvec;

		const struct UntypedExpr expr = parse_unary_expression(&tokvec);

		const struct UntypedExpr new_expr = unary_op_untyped(&expr, opkind);
		*ptr_tokvec = tokvec;
		return new_expr;
	} else if (tokvec[0].kind == RES_ALIGNOF && tokvec[1].kind == LEFT_PAREN) {
		tokvec += 2;
		if (!can_start_a_type(tokvec)) {
			fprintf(stderr, "_Alignof can only take type name\n");
			exit(EXIT_FAILURE);
		}
		struct Type type = parse_type_name(&tokvec);
		expect_and_consume(&tokvec, RIGHT_PAREN,
		                   "closing parenthesis of _Alignof(typename)");

		struct UntypedExpr expr;
		expr.category = ALIGNOF_TYPE;
		expr.operand_of_sizeof_or_alignof = type;
		*ptr_tokvec = tokvec;
		return expr;
	} else {

		struct UntypedExpr expr = parse_postfix_expression(&tokvec);
		*ptr_tokvec = tokvec;
		return expr;
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x210, %rsp            # imm = 0x210
movq %rdi, -0x210(%rbp)
movq %rdi, -0x208(%rbp)
movq %rsi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rax
cmpl $0x15, (%rax)
je 0x9c5e
movq -0x10(%rbp), %rax
cmpl $0x16, (%rax)
je 0x9c5e
movq -0x10(%rbp), %rax
cmpl $0x0, (%rax)
je 0x9c5e
movq -0x10(%rbp), %rax
cmpl $0x1, (%rax)
je 0x9c5e
movq -0x10(%rbp), %rax
cmpl $0x5, (%rax)
je 0x9c5e
movq -0x10(%rbp), %rax
cmpl $0x11, (%rax)
jne 0x9ca9
movq -0x10(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x14(%rbp)
movq -0x10(%rbp), %rax
addq $0x20, %rax
movq %rax, -0x10(%rbp)
leaq -0xb8(%rbp), %rdi
leaq -0x10(%rbp), %rsi
callq 0xa110
movq -0x210(%rbp), %rdi
movl -0x14(%rbp), %edx
leaq -0xb8(%rbp), %rsi
callq 0xa140
movq -0x10(%rbp), %rcx
movq -0x8(%rbp), %rax
movq %rcx, (%rax)
jmp 0x9e69
movq -0x10(%rbp), %rax
cmpl $0x3b, (%rax)
jne 0x9d36
movq -0x10(%rbp), %rax
cmpl $0x6, 0x20(%rax)
jne 0x9d36
movq -0x10(%rbp), %rdi
addq $0x40, %rdi
callq 0xc270
cmpl $0x0, %eax
je 0x9d36
movq -0x10(%rbp), %rax
addq $0x40, %rax
movq %rax, -0x10(%rbp)
leaq -0x108(%rbp), %rdi
leaq -0x10(%rbp), %rsi
callq 0xc400
leaq -0x10(%rbp), %rdi
movl $0x7, %esi
leaq 0xb514(%rip), %rdx      # 0x15212
callq 0xb190
movq -0x210(%rbp), %rdi
movl $0x9, 0x4(%rdi)
addq $0x48, %rdi
leaq -0x108(%rbp), %rsi
movl $0x50, %edx
callq 0x10e0
movq -0x10(%rbp), %rcx
movq -0x8(%rbp), %rax
movq %rcx, (%rax)
jmp 0x9e69
movq -0x10(%rbp), %rax
cmpl $0x32, (%rax)
je 0x9d51
movq -0x10(%rbp), %rax
cmpl $0x33, (%rax)
je 0x9d51
movq -0x10(%rbp), %rax
cmpl $0x3b, (%rax)
jne 0x9da2
movq -0x10(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x10c(%rbp)
movq -0x10(%rbp), %rax
addq $0x20, %rax
movq %rax, -0x10(%rbp)
leaq -0x1b0(%rbp), %rdi
leaq -0x10(%rbp), %rsi
callq 0x9c00
movq -0x210(%rbp), %rdi
movl -0x10c(%rbp), %edx
leaq -0x1b0(%rbp), %rsi
callq 0xa140
movq -0x10(%rbp), %rcx
movq -0x8(%rbp), %rax
movq %rcx, (%rax)
jmp 0x9e69
movq -0x10(%rbp), %rax
cmpl $0x42, (%rax)
jne 0x9e4e
movq -0x10(%rbp), %rax
cmpl $0x6, 0x20(%rax)
jne 0x9e4e
movq -0x10(%rbp), %rax
addq $0x40, %rax
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rdi
callq 0xc270
cmpl $0x0, %eax
jne 0x9df9
movq 0x1221a(%rip), %rax     # 0x1bff8
movq (%rax), %rdi
leaq 0xb452(%rip), %rsi      # 0x1523a
movb $0x0, %al
callq 0x10d0
movl $0x1, %edi
callq 0x1150
leaq -0x200(%rbp), %rdi
leaq -0x10(%rbp), %rsi
callq 0xc400
leaq -0x10(%rbp), %rdi
movl $0x7, %esi
leaq 0xb443(%rip), %rdx      # 0x1525c
callq 0xb190
movq -0x210(%rbp), %rdi
movl $0xa, 0x4(%rdi)
addq $0x48, %rdi
leaq -0x200(%rbp), %rsi
movl $0x50, %edx
callq 0x10e0
movq -0x10(%rbp), %rcx
movq -0x8(%rbp), %rax
movq %rcx, (%rax)
jmp 0x9e69
movq -0x210(%rbp), %rdi
leaq -0x10(%rbp), %rsi
callq 0xa1b0
movq -0x10(%rbp), %rcx
movq -0x8(%rbp), %rax
movq %rcx, (%rax)
movq -0x208(%rbp), %rax
addq $0x210, %rsp            # imm = 0x210
popq %rbp
retq
nopl (%rax)