// File: /workspace/github_cpp_makefile_star2_O2/menhits[P]phplus/src/CppProgram.cpp
// Function: CppProgram::pushFunc(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::shared_ptr<TypeBase>, std::shared_ptr<TypeBase>, std::shared_ptr<TypeBase>)
void CppProgram::pushFunc(const string& name, const string& cppNameHint, Type leftIn, Type rightIn, Type returnType)
{
	if (hasFunc(name))
	{
		throw PhplusError("called CppProgram::pushFunc with function name '"+name+"', which already exists", INTERNAL_ERROR);
	}
	
	globalNames->addPp(name, cppNameHint);
	
	string cppName=globalNames->getCpp(name);
	
	auto funcNames=globalNames->makeChild();
	
	string prototype;
	
	prototype+=getTypeCode(returnType);
	
	prototype+=" "+cppName+"(";
	
	bool keepTuplesTogether=true;
	
	if (keepTuplesTogether)
	{
		if (leftIn->isCreatable())
		{
			prototype+=getTypeCode(leftIn)+" me";
			funcNames->addPp("me");
		}
		
		if (rightIn->isCreatable())
		{
			if (leftIn->isCreatable())
				prototype+=", ";
			
			prototype+=getTypeCode(rightIn)+" in";
			funcNames->addPp("in");
		}
	}
	else
	{
		vector<std::pair<string, string>> args;
		
		if (leftIn->getType()==TypeBase::TUPLE)
		{
			for (auto i: *leftIn->getAllSubTypes())
			{
				args.push_back({getTypeCode(i.type), i.name});
			}
		}
		else if (!leftIn->isCreatable())
		{
			// do nothing
		}
		else
		{
			args.push_back({getTypeCode(leftIn), "me"});
		}
		
		if (rightIn->getType()==TypeBase::TUPLE)
		{
			for (auto i: *rightIn->getAllSubTypes())
			{
				args.push_back({getTypeCode(i.type), i.name});
			}
		}
		else if (!rightIn->isCreatable())
		{
			// do nothing
		}
		else
		{
			args.push_back({getTypeCode(rightIn), "in"});
		}
		
		for (int i=0; i<int(args.size()); i++)
		{
			if (i)
				prototype+=", ";
			
			prototype+=args[i].first;
			
			prototype+=" ";
			
			funcNames->addPp(args[i].second, args[i].second);
			
			prototype+=funcNames->getCpp(args[i].second);
		}
	}
	
	prototype+=")";
	
	activeFunc=CppFunc(new CppFuncBase(prototype, funcNames, returnType->isCreatable()));
	funcs[name]=activeFunc;
	funcStack.push_back(name);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x138, %rsp            # imm = 0x138
movq %r9, %r15
movq %r8, %r12
movq %rcx, %r13
movq %rdx, %rbp
movq %rsi, %rbx
movq %rdi, %r14
callq 0x17166
testb %al, %al
jne 0x1791a
movq 0xf8(%r14), %rdi
movq %rbx, %rsi
movq %rbp, %rdx
callq 0x13de2
movq 0xf8(%r14), %rsi
leaq 0x90(%rsp), %rdi
movq %rbx, %rdx
callq 0x1439e
movq 0xf8(%r14), %rsi
leaq 0x50(%rsp), %rdi
callq 0x13d84
leaq 0x70(%rsp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
movb $0x0, (%rax)
leaq 0xd0(%rsp), %rbp
movq %rbp, %rdi
movq %r15, %rsi
callq 0x12c0a
leaq 0x10(%rsp), %rdi
movq %r14, %rsi
movq %rbp, %rdx
callq 0x15e88
leaq 0x60(%rsp), %rdi
leaq 0x10(%rsp), %rsi
callq 0xa540
leaq 0x10(%rsp), %rdi
callq 0xa558
leaq 0xd8(%rsp), %rdi
callq 0xc984
leaq 0x3d46f(%rip), %rsi     # 0x54a6c
leaq 0x30(%rsp), %rdi
leaq 0x90(%rsp), %rdx
callq 0xc8a1
leaq 0x4238a(%rip), %rdx     # 0x599a0
leaq 0x10(%rsp), %rdi
leaq 0x30(%rsp), %rsi
callq 0xc882
leaq 0x60(%rsp), %rdi
leaq 0x10(%rsp), %rsi
callq 0xa540
leaq 0x10(%rsp), %rdi
callq 0xa558
leaq 0x30(%rsp), %rdi
callq 0xa558
movq (%r13), %rdi
movq (%rdi), %rax
callq *0x20(%rax)
testb %al, %al
je 0x1771a
leaq 0xc0(%rsp), %rbp
movq %rbp, %rdi
movq %r13, %rsi
callq 0x12c0a
leaq 0x30(%rsp), %rdi
movq %r14, %rsi
movq %rbp, %rdx
callq 0x15e88
leaq 0x3d7f4(%rip), %rdx     # 0x54e78
leaq 0x10(%rsp), %rdi
leaq 0x30(%rsp), %rsi
callq 0xc882
leaq 0x60(%rsp), %rdi
leaq 0x10(%rsp), %rsi
callq 0xa540
leaq 0x10(%rsp), %rdi
callq 0xa558
leaq 0x30(%rsp), %rdi
callq 0xa558
leaq 0xc8(%rsp), %rdi
callq 0xc984
movq 0x50(%rsp), %rbp
leaq 0x3d7aa(%rip), %rsi     # 0x54e79
leaq 0x10(%rsp), %rdi
leaq 0xf(%rsp), %rdx
callq 0xa150
leaq 0x3d230(%rip), %rsi     # 0x54915
leaq 0x30(%rsp), %rdi
leaq 0xe(%rsp), %rdx
callq 0xa150
leaq 0x10(%rsp), %rsi
leaq 0x30(%rsp), %rdx
movq %rbp, %rdi
callq 0x13de2
leaq 0x30(%rsp), %rdi
callq 0xa558
leaq 0x10(%rsp), %rdi
callq 0xa558
movq (%r12), %rdi
movq (%rdi), %rax
callq *0x20(%rax)
testb %al, %al
je 0x1780b
movq (%r13), %rdi
movq (%rdi), %rax
callq *0x20(%rax)
testb %al, %al
je 0x1774b
leaq 0x40754(%rip), %rsi     # 0x57e95
leaq 0x60(%rsp), %rdi
callq 0xa520
leaq 0xb0(%rsp), %r13
movq %r13, %rdi
movq %r12, %rsi
callq 0x12c0a
leaq 0x30(%rsp), %rdi
movq %r14, %rsi
movq %r13, %rdx
callq 0x15e88
leaq 0x3d707(%rip), %rdx     # 0x54e7c
leaq 0x10(%rsp), %rdi
leaq 0x30(%rsp), %rsi
callq 0xc882
leaq 0x60(%rsp), %rdi
leaq 0x10(%rsp), %rsi
callq 0xa540
leaq 0x10(%rsp), %rdi
callq 0xa558
leaq 0x30(%rsp), %rdi
callq 0xa558
leaq 0xb8(%rsp), %rdi
callq 0xc984
movq 0x50(%rsp), %r12
leaq 0x3d6bd(%rip), %rsi     # 0x54e7d
leaq 0x10(%rsp), %rdi
leaq 0xf(%rsp), %rdx
callq 0xa150
leaq 0x3d13f(%rip), %rsi     # 0x54915
leaq 0x30(%rsp), %rdi
leaq 0xe(%rsp), %rdx
callq 0xa150
leaq 0x10(%rsp), %rsi
leaq 0x30(%rsp), %rdx
movq %r12, %rdi
callq 0x13de2
leaq 0x30(%rsp), %rdi
callq 0xa558
leaq 0x10(%rsp), %rdi
callq 0xa558
leaq 0x40c87(%rip), %rsi     # 0x58499
leaq 0x60(%rsp), %rdi
callq 0xa520
movl $0xb0, %edi
callq 0xa2c0
movq %rax, %r12
leaq 0xf8(%rsp), %rdi
leaq 0x60(%rsp), %rsi
callq 0xa3b0
leaq 0x80(%rsp), %rdi
leaq 0x50(%rsp), %rsi
callq 0x185da
movq (%r15), %rdi
movq (%rdi), %rax
movb $0x1, %bpl
callq *0x20(%rax)
movzbl %al, %ecx
leaq 0xf8(%rsp), %rsi
leaq 0x80(%rsp), %rdx
movq %r12, %rdi
callq 0x14498
xorl %ebp, %ebp
leaq 0x10(%rsp), %rdi
movq %r12, %rsi
callq 0x19472
leaq 0xa0(%r14), %r15
leaq 0x10(%rsp), %rsi
movq %r15, %rdi
callq 0x198c4
leaq 0x18(%rsp), %rdi
callq 0xc984
leaq 0x88(%rsp), %rdi
callq 0xc984
leaq 0xf8(%rsp), %rdi
callq 0xa558
leaq 0xc8(%r14), %rdi
movq %rbx, %rsi
callq 0x184f4
movq %rax, %rdi
movq %r15, %rsi
callq 0x186e8
addq $0xb0, %r14
movq %r14, %rdi
movq %rbx, %rsi
callq 0x1855a
leaq 0x60(%rsp), %rdi
callq 0xa558
leaq 0x58(%rsp), %rdi
callq 0xc984
leaq 0x90(%rsp), %rdi
callq 0xa558
addq $0x138, %rsp            # imm = 0x138
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
pushq $0x38
popq %rdi
callq 0xa1b0
movq %rax, %r14
leaq 0x3d51b(%rip), %rsi     # 0x54e47
leaq 0x90(%rsp), %rdi
movq %rbx, %rdx
callq 0xc8a1
leaq 0x3d07d(%rip), %rdx     # 0x549c0
leaq 0x118(%rsp), %rdi
leaq 0x90(%rsp), %rsi
callq 0xc882
xorps %xmm0, %xmm0
leaq 0xe0(%rsp), %rcx
movaps %xmm0, (%rcx)
movb $0x1, %bpl
leaq 0x118(%rsp), %rsi
pushq $0x3
popq %rdx
movq %r14, %rdi
callq 0x19f06
xorl %ebp, %ebp
leaq 0x5fc13(%rip), %rsi     # 0x77598
leaq -0x62fa(%rip), %rdx     # 0x11692
movq %r14, %rdi
callq 0xa4e0
movq %rax, %rbx
leaq 0xe8(%rsp), %rdi
callq 0xc984
leaq 0x118(%rsp), %rdi
callq 0xa558
jmp 0x179b9
movq %rax, %rbx
movb $0x1, %bpl
leaq 0x90(%rsp), %rdi
callq 0xa558
testb %bpl, %bpl
jne 0x17a57
jmp 0x17b01
jmp 0x17a0b
jmp 0x17a1a
jmp 0x17add
movq %rax, %rbx
leaq 0x10(%rsp), %rdi
callq 0xa558
jmp 0x179ef
movq %rax, %rbx
leaq 0x30(%rsp), %rdi
callq 0xa558
jmp 0x179fe
movq %rax, %rbx
leaq 0xb8(%rsp), %rdi
jmp 0x17aa5
movq %rax, %rbx
leaq 0x30(%rsp), %rdi
callq 0xa558
jmp 0x17a1d
movq %rax, %rbx
leaq 0x10(%rsp), %rdi
jmp 0x17a82
jmp 0x17add
movq %rax, %rbx
leaq 0x10(%rsp), %rdi
callq 0xa558
jmp 0x17a3b
movq %rax, %rbx
leaq 0x30(%rsp), %rdi
callq 0xa558
jmp 0x17a4a
movq %rax, %rbx
leaq 0xc8(%rsp), %rdi
jmp 0x17aa5
movq %rax, %rbx
movq %r14, %rdi
callq 0xa230
jmp 0x17b01
movq %rax, %rbx
jmp 0x17ad3
jmp 0x17add
movq %rax, %rbx
leaq 0x10(%rsp), %rdi
callq 0xa558
jmp 0x17a7d
movq %rax, %rbx
leaq 0x30(%rsp), %rdi
callq 0xa558
jmp 0x17ae0
jmp 0x17add
movq %rax, %rbx
leaq 0x10(%rsp), %rdi
callq 0xa558
jmp 0x17a9d
movq %rax, %rbx
leaq 0xd8(%rsp), %rdi
callq 0xc984
jmp 0x17ae0
movq %rax, %rbx
jmp 0x17af4
movq %rax, %rbx
leaq 0x88(%rsp), %rdi
callq 0xc984
leaq 0xf8(%rsp), %rdi
callq 0xa558
testb %bpl, %bpl
je 0x17ae0
movq %r12, %rdi
callq 0xa2a0
jmp 0x17ae0
movq %rax, %rbx
leaq 0x60(%rsp), %rdi
callq 0xa558
leaq 0x58(%rsp), %rdi
callq 0xc984
leaq 0x90(%rsp), %rdi
callq 0xa558
movq %rbx, %rdi
callq 0xa500
nop