// File: rossy[P]crossc/SPIRV-Cross/spirv_msl.cpp
// Function: spirv_cross::CompilerMSL::emit_function_prototype(spirv_cross::SPIRFunction&, spirv_cross::Bitset const&)
void CompilerMSL::emit_function_prototype(SPIRFunction &func, const Bitset &)
{
	if (func.self != ir.default_entry_point)
		add_function_overload(func);

	local_variable_names = resource_names;
	string decl;

	processing_entry_point = (func.self == ir.default_entry_point);

	auto &type = get<SPIRType>(func.return_type);

	if (type.array.empty())
	{
		decl += func_type_decl(type);
	}
	else
	{
		// We cannot return arrays in MSL, so "return" through an out variable.
		decl = "void";
	}

	decl += " ";
	decl += to_name(func.self);
	decl += "(";

	if (!type.array.empty())
	{
		// Fake arrays returns by writing to an out array instead.
		decl += "thread ";
		decl += type_to_glsl(type);
		decl += " (&SPIRV_Cross_return_value)";
		decl += type_to_array_glsl(type);
		if (!func.arguments.empty())
			decl += ", ";
	}

	if (processing_entry_point)
	{
		decl += entry_point_args(!func.arguments.empty());

		// If entry point function has variables that require early declaration,
		// ensure they each have an empty initializer, creating one if needed.
		// This is done at this late stage because the initialization expression
		// is cleared after each compilation pass.
		for (auto var_id : vars_needing_early_declaration)
		{
			auto &ed_var = get<SPIRVariable>(var_id);
			if (!ed_var.initializer)
				ed_var.initializer = ir.increase_bound_by(1);

			set<SPIRExpression>(ed_var.initializer, "{}", ed_var.basetype, true);
		}
	}

	for (auto &arg : func.arguments)
	{
		uint32_t name_id = arg.id;

		string address_space;
		auto *var = maybe_get<SPIRVariable>(arg.id);
		if (var)
		{
			// If we need to modify the name of the variable, make sure we modify the original variable.
			// Our alias is just a shadow variable.
			if (arg.alias_global_variable && var->basevariable)
				name_id = var->basevariable;

			var->parameter = &arg; // Hold a pointer to the parameter so we can invalidate the readonly field if needed.
			address_space = get_argument_address_space(*var);
		}

		add_local_variable_name(name_id);

		if (!address_space.empty())
			decl += address_space + " ";
		decl += argument_decl(arg);

		// Manufacture automatic sampler arg for SampledImage texture
		auto &arg_type = get<SPIRType>(arg.type);
		if (arg_type.basetype == SPIRType::SampledImage && arg_type.image.dim != DimBuffer)
			decl += join(", thread const ", sampler_type(arg_type), " ", to_sampler_expression(arg.id));

		if (&arg != &func.arguments.back())
			decl += ", ";
	}

	decl += ")";
	statement(decl);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x270, %rsp            # imm = 0x270
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq -0x8(%rbp), %rcx
movq %rcx, -0x240(%rbp)
movq -0x10(%rbp), %rax
movl 0x8(%rax), %eax
cmpl 0x108(%rcx), %eax
je 0xffe21
movq -0x240(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x97940
movq -0x240(%rbp), %rdi
movq %rdi, %rsi
addq $0x488, %rsi            # imm = 0x488
addq $0x450, %rdi            # imm = 0x450
callq 0x11580
leaq -0x38(%rbp), %rdi
callq 0x7530
movq -0x240(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x8(%rax), %eax
movl 0x108(%rdi), %ecx
subl %ecx, %eax
sete 0x5d8(%rdi)
movq -0x10(%rbp), %rax
movl 0xc(%rax), %esi
callq 0xea90
movq %rax, -0x248(%rbp)
jmp 0xffe79
movq -0x248(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rdi
addq $0x20, %rdi
callq 0x8690
testb $0x1, %al
jne 0xffe97
jmp 0xffef2
movq -0x240(%rbp), %rsi
movq -0x40(%rbp), %rdx
leaq -0x70(%rbp), %rdi
callq 0x100630
jmp 0xffead
leaq -0x38(%rbp), %rdi
leaq -0x70(%rbp), %rsi
callq 0x7470
jmp 0xffebc
leaq -0x70(%rbp), %rdi
callq 0x7708
jmp 0xfff06
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x10061a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x70(%rbp), %rdi
callq 0x7708
jmp 0x10061a
leaq 0x422dc(%rip), %rsi     # 0x1421d5
leaq -0x38(%rbp), %rdi
callq 0x7510
jmp 0xfff04
jmp 0xfff06
leaq 0x3e990(%rip), %rsi     # 0x13e89d
leaq -0x38(%rbp), %rdi
callq 0x7340
jmp 0xfff18
movq -0x240(%rbp), %rsi
movq -0x10(%rbp), %rax
movl 0x8(%rax), %edx
movq (%rsi), %rax
movq 0x38(%rax), %rax
leaq -0x90(%rbp), %rdi
movl $0x1, %ecx
callq *%rax
jmp 0xfff3d
leaq -0x38(%rbp), %rdi
leaq -0x90(%rbp), %rsi
callq 0x7470
jmp 0xfff4f
leaq -0x90(%rbp), %rdi
callq 0x7708
leaq 0x4d3cb(%rip), %rsi     # 0x14d32d
leaq -0x38(%rbp), %rdi
callq 0x7340
jmp 0xfff6d
movq -0x40(%rbp), %rdi
addq $0x20, %rdi
callq 0x8690
testb $0x1, %al
jne 0x10009b
leaq 0x4d0e3(%rip), %rsi     # 0x14d06c
leaq -0x38(%rbp), %rdi
callq 0x7340
jmp 0xfff94
movq -0x240(%rbp), %rsi
movq -0x40(%rbp), %rdx
movq (%rsi), %rax
movq 0x98(%rax), %rax
leaq -0xb0(%rbp), %rdi
xorl %ecx, %ecx
callq *%rax
jmp 0xfffb6
leaq -0x38(%rbp), %rdi
leaq -0xb0(%rbp), %rsi
callq 0x7470
jmp 0xfffc8
leaq -0xb0(%rbp), %rdi
callq 0x7708
leaq 0x4d099(%rip), %rsi     # 0x14d074
leaq -0x38(%rbp), %rdi
callq 0x7340
jmp 0xfffe6
movq -0x240(%rbp), %rsi
movq -0x40(%rbp), %rdx
leaq -0xd0(%rbp), %rdi
callq 0x61340
jmp 0xfffff
leaq -0x38(%rbp), %rdi
leaq -0xd0(%rbp), %rsi
callq 0x7470
jmp 0x100011
leaq -0xd0(%rbp), %rdi
callq 0x7708
movq -0x10(%rbp), %rdi
addq $0x18, %rdi
callq 0xdb650
testb $0x1, %al
jne 0x100099
leaq 0x4455a(%rip), %rsi     # 0x14458f
leaq -0x38(%rbp), %rdi
callq 0x7340
jmp 0x100040
jmp 0x100099
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x90(%rbp), %rdi
callq 0x7708
jmp 0x10061a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0xb0(%rbp), %rdi
callq 0x7708
jmp 0x10061a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0xd0(%rbp), %rdi
callq 0x7708
jmp 0x10061a
jmp 0x10009b
movq -0x240(%rbp), %rax
testb $0x1, 0x5d8(%rax)
je 0x100226
movq -0x10(%rbp), %rdi
addq $0x18, %rdi
callq 0xdb650
movq -0x240(%rbp), %rsi
xorb $0x1, %al
movzbl %al, %edx
leaq -0xf0(%rbp), %rdi
callq 0x100a50
jmp 0x1000d6
leaq -0x38(%rbp), %rdi
leaq -0xf0(%rbp), %rsi
callq 0x7470
jmp 0x1000e8
leaq -0xf0(%rbp), %rdi
callq 0x7708
movq -0x240(%rbp), %rax
addq $0x8e0, %rax            # imm = 0x8E0
movq %rax, -0xf8(%rbp)
movq -0xf8(%rbp), %rdi
callq 0x86d0
movq %rax, -0x100(%rbp)
movq -0xf8(%rbp), %rdi
callq 0x8700
movq %rax, -0x108(%rbp)
leaq -0x100(%rbp), %rdi
leaq -0x108(%rbp), %rsi
callq 0x8730
testb $0x1, %al
jne 0x10014a
jmp 0x100224
leaq -0x100(%rbp), %rdi
callq 0x8770
movq -0x240(%rbp), %rdi
movl (%rax), %eax
movl %eax, -0x10c(%rbp)
movl -0x10c(%rbp), %esi
callq 0xfec0
movq %rax, -0x250(%rbp)
jmp 0x100179
movq -0x250(%rbp), %rax
movq %rax, -0x118(%rbp)
movq -0x118(%rbp), %rax
cmpl $0x0, 0x18(%rax)
jne 0x1001e0
movq -0x240(%rbp), %rdi
addq $0x8, %rdi
movl $0x1, %esi
callq 0x55780
movl %eax, -0x254(%rbp)
jmp 0x1001b1
movl -0x254(%rbp), %ecx
movq -0x118(%rbp), %rax
movl %ecx, 0x18(%rax)
jmp 0x1001e0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0xf0(%rbp), %rdi
callq 0x7708
jmp 0x10061a
movq -0x240(%rbp), %rdi
movq -0x118(%rbp), %rcx
movl 0x18(%rcx), %esi
addq $0xc, %rcx
movb $0x1, -0x119(%rbp)
leaq 0x4ce8e(%rip), %rdx     # 0x14d091
leaq -0x119(%rbp), %r8
callq 0x116f00
jmp 0x100211
jmp 0x100213
leaq -0x100(%rbp), %rdi
callq 0x8790
jmp 0x10012e
jmp 0x100226
movq -0x10(%rbp), %rax
addq $0x18, %rax
movq %rax, -0x128(%rbp)
movq -0x128(%rbp), %rdi
callq 0x115b0
movq %rax, -0x130(%rbp)
movq -0x128(%rbp), %rdi
callq 0x115e0
movq %rax, -0x138(%rbp)
leaq -0x130(%rbp), %rdi
leaq -0x138(%rbp), %rsi
callq 0x11610
testb $0x1, %al
jne 0x100277
jmp 0x1005e4
leaq -0x130(%rbp), %rdi
callq 0x11650
movq %rax, -0x140(%rbp)
movq -0x140(%rbp), %rax
movl 0x4(%rax), %eax
movl %eax, -0x144(%rbp)
leaq -0x168(%rbp), %rdi
callq 0x7530
movq -0x240(%rbp), %rdi
movq -0x140(%rbp), %rax
movl 0x4(%rax), %esi
callq 0x116b0
movq %rax, -0x260(%rbp)
jmp 0x1002c5
movq -0x260(%rbp), %rax
movq %rax, -0x170(%rbp)
cmpq $0x0, -0x170(%rbp)
je 0x10036b
movq -0x140(%rbp), %rax
testb $0x1, 0x10(%rax)
je 0x10031e
movq -0x170(%rbp), %rax
cmpl $0x0, 0x1c(%rax)
je 0x10031e
movq -0x170(%rbp), %rax
movl 0x1c(%rax), %eax
movl %eax, -0x144(%rbp)
jmp 0x10031e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x1005d6
movq -0x240(%rbp), %rsi
movq -0x140(%rbp), %rcx
movq -0x170(%rbp), %rax
movq %rcx, 0x68(%rax)
movq -0x170(%rbp), %rdx
leaq -0x190(%rbp), %rdi
callq 0xf34c0
jmp 0x10034c
leaq -0x168(%rbp), %rdi
leaq -0x190(%rbp), %rsi
callq 0x7430
leaq -0x190(%rbp), %rdi
callq 0x7708
movq -0x240(%rbp), %rdi
movl -0x144(%rbp), %esi
callq 0x78460
jmp 0x10037f
leaq -0x168(%rbp), %rdi
callq 0x75f0
testb $0x1, %al
jne 0x1003e8
leaq 0x3e507(%rip), %rdx     # 0x13e89d
leaq -0x1b0(%rbp), %rdi
leaq -0x168(%rbp), %rsi
callq 0x2f8c0
jmp 0x1003ab
leaq -0x38(%rbp), %rdi
leaq -0x1b0(%rbp), %rsi
callq 0x7470
jmp 0x1003bd
leaq -0x1b0(%rbp), %rdi
callq 0x7708
jmp 0x1003e8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x1b0(%rbp), %rdi
callq 0x7708
jmp 0x1005d6
movq -0x240(%rbp), %rsi
movq -0x140(%rbp), %rdx
leaq -0x1d0(%rbp), %rdi
callq 0x102680
jmp 0x100404
leaq -0x38(%rbp), %rdi
leaq -0x1d0(%rbp), %rsi
callq 0x7470
jmp 0x100416
leaq -0x1d0(%rbp), %rdi
callq 0x7708
movq -0x240(%rbp), %rdi
movq -0x140(%rbp), %rax
movl (%rax), %esi
callq 0xea90
movq %rax, -0x268(%rbp)
jmp 0x100440
movq -0x268(%rbp), %rax
movq %rax, -0x1d8(%rbp)
movq -0x1d8(%rbp), %rax
cmpl $0xe, 0xc(%rax)
jne 0x10057b
movq -0x1d8(%rbp), %rax
cmpl $0x5, 0x84(%rax)
je 0x10057b
movq -0x240(%rbp), %rsi
movq -0x1d8(%rbp), %rdx
leaq -0x218(%rbp), %rdi
callq 0x102c40
jmp 0x10048f
movq -0x240(%rbp), %rsi
movq -0x140(%rbp), %rax
movl 0x4(%rax), %edx
leaq -0x238(%rbp), %rdi
callq 0xf3250
jmp 0x1004ae
leaq 0x4cbdf(%rip), %rsi     # 0x14d094
leaq 0x3e3e1(%rip), %rcx     # 0x13e89d
leaq -0x1f8(%rbp), %rdi
leaq -0x218(%rbp), %rdx
leaq -0x238(%rbp), %r8
callq 0x116f60
jmp 0x1004d8
leaq -0x38(%rbp), %rdi
leaq -0x1f8(%rbp), %rsi
callq 0x7470
jmp 0x1004ea
leaq -0x1f8(%rbp), %rdi
callq 0x7708
leaq -0x238(%rbp), %rdi
callq 0x7708
leaq -0x218(%rbp), %rdi
callq 0x7708
jmp 0x10057b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x1d0(%rbp), %rdi
callq 0x7708
jmp 0x1005d6
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x10056d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x100561
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x1f8(%rbp), %rdi
callq 0x7708
leaq -0x238(%rbp), %rdi
callq 0x7708
leaq -0x218(%rbp), %rdi
callq 0x7708
jmp 0x1005d6
movq -0x140(%rbp), %rax
movq %rax, -0x270(%rbp)
movq -0x10(%rbp), %rdi
addq $0x18, %rdi
callq 0x11670
movq %rax, %rcx
movq -0x270(%rbp), %rax
cmpq %rcx, %rax
je 0x1005b9
leaq 0x43fe3(%rip), %rsi     # 0x14458f
leaq -0x38(%rbp), %rdi
callq 0x7340
jmp 0x1005b7
jmp 0x1005b9
leaq -0x168(%rbp), %rdi
callq 0x7708
leaq -0x130(%rbp), %rdi
callq 0x11710
jmp 0x10025b
leaq -0x168(%rbp), %rdi
callq 0x7708
jmp 0x10061a
leaq 0x4490e(%rip), %rsi     # 0x144ef9
leaq -0x38(%rbp), %rdi
callq 0x7340
jmp 0x1005f6
movq -0x240(%rbp), %rdi
leaq -0x38(%rbp), %rsi
callq 0x10200
jmp 0x100608
leaq -0x38(%rbp), %rdi
callq 0x7708
addq $0x270, %rsp            # imm = 0x270
popq %rbp
retq
leaq -0x38(%rbp), %rdi
callq 0x7708
movq -0x48(%rbp), %rdi
callq 0x7640
nopl (%rax)