// File: Mulan-Szechuan-Sauce[P]javelin/src/node.cpp
// Function: NReturn::NReturn(NExpression*)
NReturn::NReturn(NExpression *expr) : expr(expr) {
  if (funcStack == NULL) {
    throw std::runtime_error("Return statement outside of function");
  }

  Type *type = expr ? expr->get_type() : new VoidType();
  Type *declaredType = funcStack->get_type();

  if (declaredType->isUnset()) {
    // Type implication on first return
    NFunctionDeclStatement *funcDecl = funcStack->stmt;
    funcDecl->type = type;
    funcStack->set_type(type);
  } else {
    if (expr == NULL && ! declaredType->isVoid()) {
      throw std::runtime_error("Cannot return a value on a void function");
    } else if (expr != NULL) {
      expr->set_type(declaredType);
    }
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x70, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0x50(%rbp)
callq 0xbdd0
movq -0x50(%rbp), %rax
leaq 0xcd80(%rip), %rcx      # 0x1eba8
addq $0x10, %rcx
movq %rcx, (%rax)
movq -0x10(%rbp), %rcx
movq %rcx, 0x10(%rax)
leaq 0xd50a(%rip), %rax      # 0x1f348
cmpq $0x0, (%rax)
jne 0x11e97
movl $0x10, %edi
callq 0x5130
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x58(%rbp)
leaq 0x4e92(%rip), %rsi      # 0x16cf1
callq 0x50e0
jmp 0x11e66
movq -0x58(%rbp), %rdi
movq 0xd177(%rip), %rsi      # 0x1efe8
movq 0xd140(%rip), %rdx      # 0x1efb8
callq 0x53d0
movq -0x58(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
callq 0x51b0
jmp 0x11fcd
movq -0x10(%rbp), %rax
movb $0x0, -0x31(%rbp)
cmpq $0x0, %rax
je 0x11eb4
movq -0x10(%rbp), %rdi
movq (%rdi), %rax
callq *(%rax)
movq %rax, -0x60(%rbp)
jmp 0x11eea
movl $0x8, %edi
callq 0x5220
movq %rax, %rdi
movq %rdi, -0x68(%rbp)
movq %rdi, -0x30(%rbp)
movb $0x1, -0x31(%rbp)
xorl %esi, %esi
movl $0x8, %edx
callq 0x5160
movq -0x68(%rbp), %rdi
callq 0xb530
movq -0x68(%rbp), %rax
movq %rax, -0x60(%rbp)
movq -0x60(%rbp), %rax
movq %rax, -0x28(%rbp)
leaq 0xd44f(%rip), %rax      # 0x1f348
movq (%rax), %rdi
movq (%rdi), %rax
callq *(%rax)
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rdi
movq (%rdi), %rax
callq *0x10(%rax)
testb $0x1, %al
jne 0x11f15
jmp 0x11f49
leaq 0xd42c(%rip), %rax      # 0x1f348
movq (%rax), %rax
movq 0x20(%rax), %rax
movq %rax, -0x48(%rbp)
movq -0x28(%rbp), %rcx
movq -0x48(%rbp), %rax
movq %rcx, 0x20(%rax)
leaq 0xd40e(%rip), %rax      # 0x1f348
movq (%rax), %rdi
movq -0x28(%rbp), %rsi
movq (%rdi), %rax
callq *0x8(%rax)
jmp 0x11fc7
cmpq $0x0, -0x10(%rbp)
jne 0x11fae
movq -0x40(%rbp), %rdi
movq (%rdi), %rax
callq *0x18(%rax)
testb $0x1, %al
jne 0x11fae
movl $0x10, %edi
callq 0x5130
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x70(%rbp)
leaq 0x4d9d(%rip), %rsi      # 0x16d16
callq 0x50e0
jmp 0x11f80
movq -0x70(%rbp), %rdi
movq 0xd05d(%rip), %rsi      # 0x1efe8
movq 0xd026(%rip), %rdx      # 0x1efb8
callq 0x53d0
movq -0x70(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
callq 0x51b0
jmp 0x11fcd
cmpq $0x0, -0x10(%rbp)
je 0x11fc3
movq -0x10(%rbp), %rdi
movq -0x40(%rbp), %rsi
movq (%rdi), %rax
callq *0x8(%rax)
jmp 0x11fc5
jmp 0x11fc7
addq $0x70, %rsp
popq %rbp
retq
movq -0x18(%rbp), %rdi
callq 0x5400
nopw %cs:(%rax,%rax)