// File: /workspace/github_c_makefile_star2_O0/lucvoo[P]sparse-dev/inline.c
// Function: copy_expression
static struct expression * copy_expression(struct expression *expr)
{
	if (!expr)
		return NULL;

	switch (expr->type) {
	/*
	 * EXPR_SYMBOL is the interesting case, we may need to replace the
	 * symbol to the new copy.
	 */
	case EXPR_SYMBOL: {
		struct symbol *sym = copy_symbol(expr->pos, expr->symbol);
		if (sym == expr->symbol)
			break;
		expr = dup_expression(expr);
		expr->symbol = sym;
		break;
	}

	/* Atomics, never change, just return the expression directly */
	case EXPR_VALUE:
	case EXPR_STRING:
	case EXPR_FVALUE:
	case EXPR_TYPE:
		break;

	/* Unops: check if the subexpression is unique */
	case EXPR_PREOP:
	case EXPR_POSTOP: {
		struct expression *unop = copy_expression(expr->unop);
		if (expr->unop == unop)
			break;
		expr = dup_expression(expr);
		expr->unop = unop;
		break;
	}

	case EXPR_SLICE: {
		struct expression *base = copy_expression(expr->base);
		expr = dup_expression(expr);
		expr->base = base;
		break;
	}

	/* Binops: copy left/right expressions */
	case EXPR_BINOP:
	case EXPR_COMMA:
	case EXPR_COMPARE:
	case EXPR_LOGICAL: {
		struct expression *left = copy_expression(expr->left);
		struct expression *right = copy_expression(expr->right);
		if (left == expr->left && right == expr->right)
			break;
		expr = dup_expression(expr);
		expr->left = left;
		expr->right = right;
		break;
	}

	case EXPR_ASSIGNMENT: {
		struct expression *left = copy_expression(expr->left);
		struct expression *right = copy_expression(expr->right);
		if (expr->op == '=' && left == expr->left && right == expr->right)
			break;
		expr = dup_expression(expr);
		expr->left = left;
		expr->right = right;
		break;
	}

	/* Dereference */
	case EXPR_DEREF: {
		struct expression *deref = copy_expression(expr->deref);
		expr = dup_expression(expr);
		expr->deref = deref;
		break;
	}

	/* Cast/sizeof/__alignof__ */
	case EXPR_CAST:
		if (!expr->cast_expression)
			return NULL;
		if (expr->cast_expression->type == EXPR_INITIALIZER) {
			struct expression *cast = expr->cast_expression;
			struct symbol *sym = expr->cast_type;
			expr = dup_expression(expr);
			expr->cast_expression = copy_expression(cast);
			expr->cast_type = alloc_symbol(sym->pos, sym->type);
			*expr->cast_type = *sym;
			break;
		}
	case EXPR_FORCE_CAST:
	case EXPR_IMPLIED_CAST:
	case EXPR_SIZEOF: 
	case EXPR_PTRSIZEOF:
	case EXPR_ALIGNOF: {
		struct expression *cast = copy_expression(expr->cast_expression);
		if (cast == expr->cast_expression)
			break;
		expr = dup_expression(expr);
		expr->cast_expression = cast;
		break;
	}

	/* Conditional expression */
	case EXPR_SELECT:
	case EXPR_CONDITIONAL: {
		struct expression *cond = copy_expression(expr->conditional);
		struct expression *valt = copy_expression(expr->cond_true);
		struct expression *valf = copy_expression(expr->cond_false);
		if (cond == expr->conditional && valt == expr->cond_true && valf == expr->cond_false)
			break;
		expr = dup_expression(expr);
		expr->conditional = cond;
		expr->cond_true = valt;
		expr->cond_false = valf;
		break;
	}

	/* Statement expression */
	case EXPR_STATEMENT: {
		struct statement *stmt = alloc_statement(expr->pos, STMT_COMPOUND);
		copy_statement(expr->statement, stmt);
		expr = dup_expression(expr);
		expr->statement = stmt;
		break;
	}

	/* Call expression */
	case EXPR_CALL: {
		struct expression *fn = copy_expression(expr->fn);
		struct expression_list *list = expr->args;
		struct expression *arg;

		expr = dup_expression(expr);
		expr->fn = fn;
		expr->args = NULL;
		FOR_EACH_PTR(list, arg) {
			add_expression(&expr->args, copy_expression(arg));
		} END_FOR_EACH_PTR(arg);
		break;
	}

	/* Initializer list statement */
	case EXPR_INITIALIZER: {
		struct expression_list *list = expr->expr_list;
		struct expression *entry;
		expr = dup_expression(expr);
		expr->expr_list = NULL;
		FOR_EACH_PTR(list, entry) {
			add_expression(&expr->expr_list, copy_expression(entry));
		} END_FOR_EACH_PTR(entry);
		break;
	}

	/* Label in inline function - hmm. */
	case EXPR_LABEL: {
		struct symbol *label_symbol = copy_symbol(expr->pos, expr->label_symbol);
		expr = dup_expression(expr);
		expr->label_symbol = label_symbol;
		break;
	}

	case EXPR_INDEX: {
		struct expression *sub_expr = copy_expression(expr->idx_expression);
		expr = dup_expression(expr);
		expr->idx_expression = sub_expr;
		break;
	}
		
	case EXPR_IDENTIFIER: {
		struct expression *sub_expr = copy_expression(expr->ident_expression);
		expr = dup_expression(expr);
		expr->ident_expression = sub_expr;
		break;
	}

	/* Position in initializer.. */
	case EXPR_POS: {
		struct expression *val = copy_expression(expr->init_expr);
		expr = dup_expression(expr);
		expr->init_expr = val;
		break;
	}
	case EXPR_OFFSETOF: {
		struct expression *val = copy_expression(expr->down);
		if (expr->op == '.') {
			if (expr->down != val) {
				expr = dup_expression(expr);
				expr->down = val;
			}
		} else {
			struct expression *idx = copy_expression(expr->index);
			if (expr->down != val || expr->index != idx) {
				expr = dup_expression(expr);
				expr->down = val;
				expr->index = idx;
			}
		}
		break;
	}
	case EXPR_GENERIC:
		expr = dup_expression(expr);
		expr->control = copy_expression(expr->control);
		if (!evaluate_expression(expr))
			return NULL;
		expr = copy_expression(expr);
		break;

	default:
		warning(expr->pos, "trying to copy expression type %d", expr->type);
	}
	return expr;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x140, %rsp            # imm = 0x140
movq %rdi, -0x10(%rbp)
cmpq $0x0, -0x10(%rbp)
jne 0x16023
movq $0x0, -0x8(%rbp)
jmp 0x16876
movq -0x10(%rbp), %rax
movzbl (%rax), %eax
decl %eax
movl %eax, %ecx
movq %rcx, -0x128(%rbp)
subl $0x1e, %eax
ja 0x1684c
movq -0x128(%rbp), %rax
leaq 0x4c2f8(%rip), %rcx     # 0x62344
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x10(%rbp), %rax
movq -0x10(%rbp), %rcx
movq 0x20(%rcx), %rsi
movq 0x8(%rax), %rdi
callq 0x15f30
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rax
movq -0x10(%rbp), %rcx
cmpq 0x20(%rcx), %rax
jne 0x16081
jmp 0x1686e
movq -0x10(%rbp), %rdi
callq 0x16a90
movq %rax, -0x10(%rbp)
movq -0x18(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x20(%rax)
jmp 0x1686e
jmp 0x1686e
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rdi
callq 0x16000
movq %rax, -0x20(%rbp)
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rax
cmpq -0x20(%rbp), %rax
jne 0x160c8
jmp 0x1686e
movq -0x10(%rbp), %rdi
callq 0x16a90
movq %rax, -0x10(%rbp)
movq -0x20(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x20(%rax)
jmp 0x1686e
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rdi
callq 0x16000
movq %rax, -0x28(%rbp)
movq -0x10(%rbp), %rdi
callq 0x16a90
movq %rax, -0x10(%rbp)
movq -0x28(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x20(%rax)
jmp 0x1686e
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rdi
callq 0x16000
movq %rax, -0x30(%rbp)
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rdi
callq 0x16000
movq %rax, -0x38(%rbp)
movq -0x30(%rbp), %rax
movq -0x10(%rbp), %rcx
cmpq 0x20(%rcx), %rax
jne 0x16158
movq -0x38(%rbp), %rax
movq -0x10(%rbp), %rcx
cmpq 0x28(%rcx), %rax
jne 0x16158
jmp 0x1686e
movq -0x10(%rbp), %rdi
callq 0x16a90
movq %rax, -0x10(%rbp)
movq -0x30(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x20(%rax)
movq -0x38(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x28(%rax)
jmp 0x1686e
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rdi
callq 0x16000
movq %rax, -0x40(%rbp)
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rdi
callq 0x16000
movq %rax, -0x48(%rbp)
movq -0x10(%rbp), %rax
cmpl $0x3d, 0x4(%rax)
jne 0x161cf
movq -0x40(%rbp), %rax
movq -0x10(%rbp), %rcx
cmpq 0x20(%rcx), %rax
jne 0x161cf
movq -0x48(%rbp), %rax
movq -0x10(%rbp), %rcx
cmpq 0x28(%rcx), %rax
jne 0x161cf
jmp 0x1686e
movq -0x10(%rbp), %rdi
callq 0x16a90
movq %rax, -0x10(%rbp)
movq -0x40(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x20(%rax)
movq -0x48(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x28(%rax)
jmp 0x1686e
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rdi
callq 0x16000
movq %rax, -0x50(%rbp)
movq -0x10(%rbp), %rdi
callq 0x16a90
movq %rax, -0x10(%rbp)
movq -0x50(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x20(%rax)
jmp 0x1686e
movq -0x10(%rbp), %rax
cmpq $0x0, 0x28(%rax)
jne 0x16240
movq $0x0, -0x8(%rbp)
jmp 0x16876
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rax
movl (%rax), %eax
andl $0xff, %eax
cmpl $0x18, %eax
jne 0x162cc
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rax
movq %rax, -0x58(%rbp)
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0x60(%rbp)
movq -0x10(%rbp), %rdi
callq 0x16a90
movq %rax, -0x10(%rbp)
movq -0x58(%rbp), %rdi
callq 0x16000
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x28(%rax)
movq -0x60(%rbp), %rax
movq -0x60(%rbp), %rcx
movl (%rcx), %esi
andl $0xff, %esi
movq 0x4(%rax), %rdi
callq 0x3f4d0
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x20(%rax)
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rdi
movq -0x60(%rbp), %rsi
movl $0xe0, %edx
callq 0x111d0
jmp 0x1686e
jmp 0x162ce
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rdi
callq 0x16000
movq %rax, -0x68(%rbp)
movq -0x68(%rbp), %rax
movq -0x10(%rbp), %rcx
cmpq 0x28(%rcx), %rax
jne 0x162f2
jmp 0x1686e
movq -0x10(%rbp), %rdi
callq 0x16a90
movq %rax, -0x10(%rbp)
movq -0x68(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x28(%rax)
jmp 0x1686e
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rdi
callq 0x16000
movq %rax, -0x70(%rbp)
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rdi
callq 0x16000
movq %rax, -0x78(%rbp)
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rdi
callq 0x16000
movq %rax, -0x80(%rbp)
movq -0x70(%rbp), %rax
movq -0x10(%rbp), %rcx
cmpq 0x20(%rcx), %rax
jne 0x16372
movq -0x78(%rbp), %rax
movq -0x10(%rbp), %rcx
cmpq 0x28(%rcx), %rax
jne 0x16372
movq -0x80(%rbp), %rax
movq -0x10(%rbp), %rcx
cmpq 0x30(%rcx), %rax
jne 0x16372
jmp 0x1686e
movq -0x10(%rbp), %rdi
callq 0x16a90
movq %rax, -0x10(%rbp)
movq -0x70(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x20(%rax)
movq -0x78(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x28(%rax)
movq -0x80(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x30(%rax)
jmp 0x1686e
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdi
movl $0x3, %esi
callq 0x23020
movq %rax, -0x88(%rbp)
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rdi
movq -0x88(%rbp), %rsi
callq 0x154d0
movq -0x10(%rbp), %rdi
callq 0x16a90
movq %rax, -0x10(%rbp)
movq -0x88(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x20(%rax)
jmp 0x1686e
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rdi
callq 0x16000
movq %rax, -0x90(%rbp)
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rax
movq %rax, -0x98(%rbp)
movq -0x10(%rbp), %rdi
callq 0x16a90
movq %rax, -0x10(%rbp)
movq -0x90(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x20(%rax)
movq -0x10(%rbp), %rax
movq $0x0, 0x28(%rax)
movq -0x98(%rbp), %rax
movq %rax, -0xa8(%rbp)
movq -0xa8(%rbp), %rax
movq %rax, -0xb0(%rbp)
movq -0xa8(%rbp), %rax
movq %rax, -0xb8(%rbp)
cmpq $0x0, -0xa8(%rbp)
jne 0x1647a
jmp 0x16542
jmp 0x1647c
movl $0x0, -0xbc(%rbp)
movl -0xbc(%rbp), %eax
movq -0xb0(%rbp), %rcx
movw (%rcx), %cx
shlw $0x8, %cx
sarw $0x8, %cx
movswl %cx, %ecx
cmpl %ecx, %eax
jge 0x16521
movq -0xb0(%rbp), %rax
movslq -0xbc(%rbp), %rcx
movq 0x18(%rax,%rcx,8), %rax
movq %rax, -0xa0(%rbp)
movq -0xb0(%rbp), %rax
movw (%rax), %ax
sarw $0x8, %ax
cwtl
cmpl $0x0, %eax
je 0x164df
cmpq $0x0, -0xa0(%rbp)
jne 0x164df
jmp 0x1650d
movq -0x10(%rbp), %rax
addq $0x20, %rax
addq $0x8, %rax
movq %rax, -0x130(%rbp)
movq -0xa0(%rbp), %rdi
callq 0x16000
movq -0x130(%rbp), %rdi
movq %rax, %rsi
callq 0x16ae0
movl -0xbc(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xbc(%rbp)
jmp 0x16486
jmp 0x16523
movq -0xb0(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0xb0(%rbp)
cmpq -0xa8(%rbp), %rax
jne 0x1647c
jmp 0x1686e
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0xc8(%rbp)
movq -0x10(%rbp), %rdi
callq 0x16a90
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rax
movq $0x0, 0x20(%rax)
movq -0xc8(%rbp), %rax
movq %rax, -0xd8(%rbp)
movq -0xd8(%rbp), %rax
movq %rax, -0xe0(%rbp)
movq -0xd8(%rbp), %rax
movq %rax, -0xe8(%rbp)
cmpq $0x0, -0xd8(%rbp)
jne 0x165a8
jmp 0x1666c
jmp 0x165aa
movl $0x0, -0xec(%rbp)
movl -0xec(%rbp), %eax
movq -0xe0(%rbp), %rcx
movw (%rcx), %cx
shlw $0x8, %cx
sarw $0x8, %cx
movswl %cx, %ecx
cmpl %ecx, %eax
jge 0x1664b
movq -0xe0(%rbp), %rax
movslq -0xec(%rbp), %rcx
movq 0x18(%rax,%rcx,8), %rax
movq %rax, -0xd0(%rbp)
movq -0xe0(%rbp), %rax
movw (%rax), %ax
sarw $0x8, %ax
cwtl
cmpl $0x0, %eax
je 0x1660d
cmpq $0x0, -0xd0(%rbp)
jne 0x1660d
jmp 0x16637
movq -0x10(%rbp), %rax
addq $0x20, %rax
movq %rax, -0x138(%rbp)
movq -0xd0(%rbp), %rdi
callq 0x16000
movq -0x138(%rbp), %rdi
movq %rax, %rsi
callq 0x16ae0
movl -0xec(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xec(%rbp)
jmp 0x165b4
jmp 0x1664d
movq -0xe0(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0xe0(%rbp)
cmpq -0xd8(%rbp), %rax
jne 0x165aa
jmp 0x1686e
movq -0x10(%rbp), %rax
movq -0x10(%rbp), %rcx
movq 0x20(%rcx), %rsi
movq 0x8(%rax), %rdi
callq 0x15f30
movq %rax, -0xf8(%rbp)
movq -0x10(%rbp), %rdi
callq 0x16a90
movq %rax, -0x10(%rbp)
movq -0xf8(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x20(%rax)
jmp 0x1686e
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rdi
callq 0x16000
movq %rax, -0x100(%rbp)
movq -0x10(%rbp), %rdi
callq 0x16a90
movq %rax, -0x10(%rbp)
movq -0x100(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x28(%rax)
jmp 0x1686e
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rdi
callq 0x16000
movq %rax, -0x108(%rbp)
movq -0x10(%rbp), %rdi
callq 0x16a90
movq %rax, -0x10(%rbp)
movq -0x108(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x38(%rax)
jmp 0x1686e
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rdi
callq 0x16000
movq %rax, -0x110(%rbp)
movq -0x10(%rbp), %rdi
callq 0x16a90
movq %rax, -0x10(%rbp)
movq -0x110(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x28(%rax)
jmp 0x1686e
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rdi
callq 0x16000
movq %rax, -0x118(%rbp)
movq -0x10(%rbp), %rax
cmpl $0x2e, 0x4(%rax)
jne 0x1679a
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rax
cmpq -0x118(%rbp), %rax
je 0x16798
movq -0x10(%rbp), %rdi
callq 0x16a90
movq %rax, -0x10(%rbp)
movq -0x118(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x28(%rax)
jmp 0x167fd
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rdi
callq 0x16000
movq %rax, -0x120(%rbp)
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rax
cmpq -0x118(%rbp), %rax
jne 0x167d0
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rax
cmpq -0x120(%rbp), %rax
je 0x167fb
movq -0x10(%rbp), %rdi
callq 0x16a90
movq %rax, -0x10(%rbp)
movq -0x118(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x28(%rax)
movq -0x120(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x30(%rax)
jmp 0x167fd
jmp 0x1686e
movq -0x10(%rbp), %rdi
callq 0x16a90
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rdi
callq 0x16000
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x20(%rax)
movq -0x10(%rbp), %rdi
callq 0x4bb70
cmpq $0x0, %rax
jne 0x1683d
movq $0x0, -0x8(%rbp)
jmp 0x16876
movq -0x10(%rbp), %rdi
callq 0x16000
movq %rax, -0x10(%rbp)
jmp 0x1686e
movq -0x10(%rbp), %rax
movq -0x10(%rbp), %rcx
movl (%rcx), %edx
andl $0xff, %edx
movq 0x8(%rax), %rdi
leaq 0x4bba2(%rip), %rsi     # 0x62409
movb $0x0, %al
callq 0x16d80
movq -0x10(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x140, %rsp            # imm = 0x140
popq %rbp
retq
nopw %cs:(%rax,%rax)